Reputation: 28803
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
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
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