« CakePHP SQL ListsKalabaaz adopts Piclens »


CakePHP :: The Threaded type

After going through the neighbors and list types of $model->find method, we finally look at the "threaded" type. We fetch the threaded type result in a similar fashion as other types:

$model->find("threaded", $conditions);

So when and why would you need it? You'd want to use the threaded type when retrieving any records that have a parent-child relationship. For example in forums or comments you may begin a topic based on subject and find all responses to that particular topic which would essentially be the children of the original topic. And that relationship could be recursive, in the sense, that you may have further children within the topic for a sub-topic. Most comment forums use these kinds of recursive threads.

Let's look at a classic example of parent-child relationship. Say you're writing an article or post which spans multiple pages. You want the option to have the first page act as the parent and all subsequent pages for this article to be children of the first page. You can either create an articles table in your database and then create a second table that holds the parent-child relationships for these articles. That is an option but seems wasteful. It'll be more efficient if you create an additional field in the articles table and call it parent_id (Cake naming conventions are simpler to work with, if you call it parent_id as opposed to say article_daddy or some other maverick name) Since the content structure of each page is identical your SQL for articles table creation may look like this:

CREATE TABLE IF NOT EXISTS articles (
    id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
    parent_id MEDIUMINT UNSIGNED NOT NULL DEFAULT "0",
    author_id SMALLINT UNSIGNED NOT NULL DEFAULT "0",
    title VARCHAR(255) NOT NULL DEFAULT "",
    content LONGTEXT NOT NULL DEFAULT "",
    created DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
    modified DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
    PRIMARY KEY  (id),
    KEY parent_id (parent_id)
) ENGINE = MYISAM;

Now the parent_id field will hold the id of the parent page within the same table. And you can fetch all your articles like this:

/* Action in your ArticlesController */
public function articleList(){

    //Create findConditions
    $cond["fields"] = array("Article.id", "Article.parent_id", "Article.title",
"Article.author_id", "Article.created"); $cond["order"] = "Article.created"; $cond["recursive"] = -1; return $this->Article->find("threaded", $cond); }

Which should generate a query something on these on these lines:

SELECT `Article`.`id`, `Article`.`parent_id`,
`Article`.`title`, `Article`.`author_id`, `Article`.`created`
FROM `articles` AS `Article`
WHERE 1 = 1
ORDER BY `Article`.`created` ASC

Now, the results for this are processed by CAKEPHP and available in the following format:

Array
(
[0] => Array
(
    [Article] => Array
    (
        [id] => 9
        [parent_id] => 0
        [title] => A promising fraud
        [author_id] =>1
        [created] => 2008-07-07 03:35:52
    )

    [children] => Array
    (
        [0] => Array
        (
            [Article] => Array
            (
                [id] => 12
                [parent_id] => 9
            [title] => Finding neighbors
            [author_id] =>1
            [created] => 2008-07-13 15:13:39
            )

            [children] => Array
            (
            )

        )

        [1] => Array
        (
            [Article] => Array
            (
            [id] => 17
            [parent_id] => 9
            [title] => The Threaded type
            [author_id] => 1
            [created] => 2008-07-16 17:50:56
            )

            [children] => Array
            (
            )

        )

    )
)

[1] => Array
(
    [Article] => Array
    (
        [id] => 13
        [parent_id] => 0
        [title] => CakePHP SQL Lists
        [author_id] => 1
        [created] => 2008-07-15 00:56:27
    )

    [children] => Array
    (
    )

)

[2] => Array
(
    [Article] => Array
    (
        [id] => 16
        [parent_id] => 0
        [title] => Internet killed the Video Star
        [author_id] => 1
        [created] => 2008-07-16 04:08:14
    )

    [children] => Array
    (
    )
)
)

So the result is an indexed array and each index contains an associative array with 2 keys: Article (or your Model Name) & children. The children array is recursive as in each child object will further return children. If the children array is empty, then no more children exist for that particular entry. Now you may loop through this in your view and display it anyway you want.

This completes the find method for the model class where we looked at neighbors, list and now threaded types. As of Cake 1.2 it is recommended that you use a singular find and deprecate the use of findAll, findCount or any other find variation that exists in earlier versions of Cake.

Hope that helped.

1 response
Have your say

  1. amanaman |

    nice features good one

Leave a reply fields marked * are required