Adding Comments to a CakePHP Blog App (hasMany, belongsTo)

One of the most powerful features of CakePHP is the ability to handle model associations, at its very simplest an association occurs when some data in the database is related to some other data. In normal PHP applications you would normally have to write a custom SQL statement that will grab the data using a JOIN statement. Obviously this kind of custom query can be accomplished in CakePHP but it will automatically grab all the related data as long as you have specified the relationship in the Model file.

In a simple example i'm going to stick with the mandatory 'Blog Application' and add a comment system, so that people can assign comments to posts. Before starting I recommend reading the Associations section in the manual and my previous post about using the 'bake' script.

Creating the Comments Table

The first thing we should do, as with all applications you build, is create the database. I'm going to be following on from my previous posts and at the moment i only have 2 tables which include 'posts' and 'users'. We need another to hold the 'comments' information and the most important field in the table is the 'post_id' column which indicates which post the comment belongs to and acts as a foreign key.

CakePHP expects this to be in a very specific format, and this the name of the model followed by '_id', in PHP terms this is very common and hopefully it should come as second nature to you, if not then follow this practice and you should be fine. Below is the SQL statement used to generate the 'comments' table.

CREATE TABLE `comments` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`post_id` INT NOT NULL ,
	`name` VARCHAR( 255 ) NOT NULL ,
	`email` VARCHAR( 255 ) NOT NULL ,
	`text` TEXT NOT NULL ,
	`created` DATETIME NOT NULL
);

Creating the Models and Relationships

With any new table in the database we also need a Model, View and Controller files, so create a file called 'comment.php' in the 'models' folder. This is where the relationships between models need to be defined, in this case we need to setup a 'belongTo' association. This is the correct association to use because a comment can only belong to a single post, at this stage we are only going to use the 'className' variable. By reading the manual you will find there are plenty of options to use so that your can order or limit the related data.

class Comment extends AppModel {
	var $name = 'Comment';
	var $belongsTo = array('Post'=>array('className'=>'Post'));
}

We also need to define the association in the 'post' model so that the relationship works both ways, i.e. a post can see its comments and a comment can see the post it belongs to. The association in the 'post' model is going to be a 'hasMany' and is created the same way as before, again we will just be using the 'className' variable.

class Post extends AppModel {
	var $name = 'Post';
	var $hasMany = array('Comment'=>array('className'=>'Comment'));
}

Baking the Blog Application

Baking with CakePHP

Now that we have setup our Models, we need to go through the process of baking our Controller Files and our View Files, if you dont know how to do this then please go through my previous post as i wont be going through it here. Hopefully if your Model files do not contain errors you should not encounter any problems with the bake script.

Another great thing about the Bake script is that it will automatically create the code for displaying related data, so if your still finding your way around CakePHP and dont know how things relate just yet you can look at the generated source code.

Have a look at your application in a browser, when viewing a post you should be able to add a comment to that post and if you have already done so, see a list of comments that have been added. Just like with the posts you will be able to add, edit and delete comments and all the necessary views and application logic has been created for you.

Comments in CakePHP Related Comments in CakePHP

How CakePHP works with related data

If we have a look at the data for one of the posts using the 'print_r()' php function we can see that CakePHP gets all the post information as well as all the related comments. This happens automatically when a $this->Post->read() or $this->Post->findAll() call is made. To access the post information we simply need to access the $post['Post'] array and for the comments we can simply loop through them all using foreach($post['Comment'] as $comment).

Array
(
    [Post] => Array
        (
            [id] => 1
            [title] => The title
            [body] => This is the post body.
            [created] => 2007-12-28 13:54:34
            [modified] => 
        )
    [Comment] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [post_id] => 1
                    [name] => James
                    [email] => info@jamesfairhurst.co.uk
                    [text] => This is a sample comment.
                    [created] => 0000-00-00 00:00:00
                )
            [1] => Array
                (
                    [id] => 2
                    [post_id] => 1
                    [name] => James
                    [email] => info@jamesfairhurst.co.uk
                    [text] => This is another sample comment.
                    [created] => 0000-00-00 00:00:00
                )
        )
)

Because the associations were setup both ways CakePHP also grabs the post information when viewing a comment, and this can be seen in the comment data.

Array
(
    [Comment] => Array
        (
            [id] => 1
            [post_id] => 1
            [name] => James
            [email] => info@jamesfairhurst.co.uk
            [text] => This is a sample comment.
            [created] => 0000-00-00 00:00:00
        )
    [Post] => Array
        (
            [id] => 1
            [title] => The title
            [body] => This is the post body.
            [created] => 2007-12-28 13:54:34
            [modified] => 
        )
)

This is standard CakePHP way of getting related data so once you get to grips with using and accessing your data in this way it will become second nature in the future.

Wrapping Up

Setting up an application that uses associated data is really quite simple in CakePHP, to make sure that everything will work you need to make sure that your database and Models have been setup correctly. Usually if this is not the case you will encounter errors when baking your application. Just remember that you will need to properly setup all the foreign and primary keys in the database using the proper CakePHP naming conventions. A quick look in the manual will point you in the right direction if you are having problems or alternatively just drop me an email or comment and i'll respond as soon as can.

Posted on 8th February 2008
on 8/2/08

comments powered by Disqus