Cameron
Cameron

Reputation: 28803

CakePHP: List comments associated with a post

In my application I have two tables (I have more but I'm only discussing two here):

**Posts**
id
title
datetime
content

**Comments**
id
content
post_id
user_id

As you can see their is a relationship using the post_id as a foreign key.

When viewing the Post I have the following code to display comments:

<?php if ( ! empty($post['Comment']) ): ?>
        <ul>
            <?php foreach ($post['Comment'] as $comment): ?>
            <li>
                <?php echo $comment['title']; ?>
            </li>
            <?php endforeach; ?>
        </ul>
        <?php else: ?>
        <p>No comments...</p>
        <?php endif; ?>

Here is the controller method for viewing a post:

function view ( $id = null, $slug = null )
    {
        $post = $this->Post->find('first',array('contain'=>array('User'=>array('Comment','Profile')),'conditions'=>array('Post.id'=>Tiny::reverseTiny($id))));

        if (!$post)
        {
            throw new NotFoundException('404');
        }
        else if($post['Post']['status'] == '0') // 0=draft 1=open 2=open
        {
            if($post['Post']['user_id'] == $this->Auth->user('id'))
            {
                $this->Session->setFlash('Your post has NOT been published yet');
            }
            else
            {
                throw new NotFoundException('404');
            }
        }

        if (Inflector::slug($post['Post']['title']) != $slug || $slug = null)
        {
            $this->redirect(array('id'=>Tiny::toTiny($post['Post']['id']),'slug'=>Inflector::slug($post['Post']['title'])));
        }

        $this->set(compact('post'));
    }

and this is the comment model:

class Comment extends AppModel
{
    public $name = 'Comment';

    public $belongsTo = array('User','Post');

    public $actsAs = array('Containable');
}

and a typical url for a post would be: /posts/Sample_post-1ns

However I ALWAYS get the message that there are no comments... But I have looked in the database and their is... and I have double checked that all the associations are correct. So I can only presume that the code above is wrong!

Also is their a better way of calling the comments? As I want to add the ability to filter and paginate them too.

Cheers

Upvotes: 0

Views: 1617

Answers (2)

Jon Cairns
Jon Cairns

Reputation: 11951

From your schema it looks like the comment model is related to the post model, not to the user, so:

$post = $this->Post->find('first',array('contain'=>array('User'=>array('Comment','Profile')),'conditions'=>array('Post.id'=>Tiny::reverseTiny($id))));

Should be:

$post = $this->Post->find('first',array('contain'=>array('Comment','User'=>array('Profile')),'conditions'=>array('Post.id'=>Tiny::reverseTiny($id))));

I.e. the Comment should be outside of the User contain array.

Providing that the correct hasMany and belongsTo relationships are set up on the Post/User and Comment model respectively, the first example would produce an array like this:

 array(
    'Post'=>array(...),
    'User'=>array(
        'id'=>1,
         //Other user data

         'Comment'=>array(
              array(...), //Comment 1
              array(...), //Comment 2
          )
     )
 );

And the second example would produce:

array(
    'Post'=>array(...),
    'User'=>array('id'=>1 //Other user data)
    'Comment'=>array(
          array(...), //Comment 1
          array(...), //Comment 2
     )
 );

Hopefully, that shows that the difference is in the position of the "Comment" key in the array - it is either under the User key, or at the top level depending on how you do the contain.

Upvotes: 1

Paulo Rodrigues
Paulo Rodrigues

Reputation: 5303

Seems you need something like this:

Comment model:

public $belongsTo = array('User', 'Post');

Post model:

public $belongsTo = array('User');
public $hasMany = array('Comment');

User model:

public $hasMany = array('Post', 'Comment');

And contain statement of Post:

'contain' => array('Comment', 'User' => array('Comment', 'Profile'))

Upvotes: 3

Related Questions