Attach Comments to Any Model in CakePHP

This method of linking models allows you to have a single table of data, say Comment, that is related to any one of a number of other Models (eg: Post, Event).

The Models

Before we get started, lets setup the models.

models/comment.php
class Comment extends AppModel {
        var $name = 'Comment';
}
models/post.php
class Post extends AppModel {
        var $name = 'Post';
        var $hasMany = array(
                'Comment' => array(
                        'className' => 'Comment',
                        'foreignKey' => 'foreign_id',
                        'conditions' => array('Comment.class'=>'Post'),
                ),
        );
}
models/event.php
class Event extends AppModel {
        var $name = 'Event';
        var $hasMany = array(
                'Comment' => array(
                        'className' => 'Comment',
                        'foreignKey' => 'foreign_id',
                        'conditions' => array('Comment.class'=>'Event'),
                ),
        );
}

The Controller

Now to save the data.

views/posts/view.ctp
<?php echo $form->create('Post');?>
        <fieldset>
                <legend><?php __('Post Details');?></legend>
        <?php
                echo $form->input('Comment.name');
                echo $form->input('Comment.body');
        ?>
        </fieldset>
<?php echo $form->end('Submit');?>
controllers/posts_controller.php
class PostsController extends AppController {
        var $name = 'Posts';

        function view($id = null) {
                if (!$id) {
                        $this->_flash(__('Invalid Post.', true),'error');
                        $this->redirect(array('action'=>'index'));
                }

                // save the comment
                if (!empty($this->data['Comment'])) {
                        $this->data['Comment']['class'] = 'Post';
                        $this->data['Comment']['foreign_id'] = $id;
                        $this->Post->Comment->create();
                        if ($this->Post->Comment->save($this->data)) {
                                $this->_flash(__('The Comment has been saved.', true),'success');
                                $this->redirect(array('action'=>'view',$id));
                        }
                        $this->_flash(__('The Comment could not be saved. Please, try again.', true),'warning');
                }

                // set the view variables
                $post = $this->Post->read(null, $id); // contains $post['Comments']
                $this->set(compact('post'));
        }
}

In Conclusion

That's all there is to it, now you can save comments related to any other model record!

Post new comment

  • Allowed HTML tags: <b> <br> <p> <a> <strong> <cite> <em> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • You may use [img:xx] tags to display uploaded files or images inline.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <css>, <diff>, <drupal5>, <html>, <javascript>, <php>. Beside the tag style "<foo>" it is also possible to use "[foo]". PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options