我在CakePHP的find()方法和'更深层'模型关联中遇到了一些问题。有一些这些,但到目前为止我找不到答案。
我的模型关联分别为User hasMany Post hasMany Comment hasMany Vote
和Vote belongsTo Comment belongsTo Post belongsTo User
。 belongsTo
关联使用内部联接('type'=>'INNER')。
如何使用CakePHP的model-> find()方法查找特定用户帖子的所有评论投票?
我故意使用了四个模型链,因为这似乎适用于直接关联模型中的条件。所以没有在相邻表中使用外键保持列(条件'Post.user_id == 1'而不是'User.id == 1')。
在SQL中,这将是:
SELECT v.*
FROM votes v
JOIN comments c ON (v.comment_id = c.id)
JOIN posts p ON (c.post_id = p.id)
JOIN users u ON (p.user_id = u.id)
WHERE u.id = 1
我无法使用find()+ Containable行为重现这些连接。虽然我可以简单地让用户获得他所有的数据,但我必须从结果数组中收集所有投票。
它不是这样的(警告:未知列'User.id'):
$this->Vote->recursive = 2; // or higher
$this->Vote->find('all',array('conditions' => array('User.id' => 1)));
事实上,只要我添加条件,这甚至不能使用Post而不是User(Vote-> Comment-> Post)。制造的SQL查询仅加入投票和评论。
返回的数组应该只包含上面的SQL查询将返回的投票,其他所有内容都应该在此过程中“加入”。
注意:我的问题非常接近这个,这帮助我入门: In cakephp how can I do a find with conditions on a related field?
答案 0 :(得分:16)
$joins = array(
array('table'=>'comments',
'alias' => 'Comment',
'type'=>'inner',
'conditions'=> array(
'Comment.id = Vote.comment_id'
)),
array('table'=>'posts',
'alias' => 'Post',
'type'=>'inner',
'conditions'=> array(
'Post.id = Comment.post_id'
)),
array('table'=>'users',
'alias' => 'User',
'type'=>'inner',
'conditions'=> array(
'User.id = Post.user_id','User.id'=>$user_id
))
);
$votes = $this->Vote->find('all',array('joins'=>$joins,'recursive'=>-1));
答案 1 :(得分:7)
使用Containable行为在关联的模型上执行条件。我花了一点时间来挖掘它,但它就像一个魅力!并且它使用LEFT JOIN,因此它仍将拉入原始模型的所有值。
这样的事情应该有效:
$this->Vote->Behaviors->attach('Containable');
$this->Vote->find('all',array(
'contain'=>array(
'Comment'=>array(
'Post'=>array(
'User'=>array(
'conditions'=>array(
'User.id'=>1,
),
),
),
),
),
));
如果您想要包含投票人的用户数据,您只需在初始数组中再添加一项:
$this->Vote->Behaviors->attach('Containable');
$this->Vote->find('all',array(
'contain'=>array(
'Comment'=>array(
'Post'=>array(
'User'=>array(
'conditions'=>array(
'User.id'=>1,
),
),
),
),
'User',
),
));
希望有所帮助!
答案 2 :(得分:1)
这可能是您需要使用query method的时间之一。
你不能或不想通过其他模型方法进行的SQL调用(小心 - 很少有情况这是真的)可以使用模型的query()方法进行。
$votes = $this->Vote->query('SELECT Vote.* FROM votes Vote
JOIN comments Comment ON (Vote.comment_id = Comment.id)
JOIN posts Post ON (Comment.post_id = Post.id)
JOIN users User ON (Post.user_id = User.id)
WHERE User.id = 1');
这应该返回一个投票条目数组,就像find方法一样。
foreach ($votes as $vote):
echo $vote['Vote']['id'];
endforeach;
答案 3 :(得分:0)
您可以显式连接表,而不是执行自定义SQL查询,以便按间接关联表的字段进行筛选。请查看此页面,了解如何通过评论加入投票和用户: http://book.cakephp.org/view/872/Joining-tables