任何人都可以告诉我,如何从cakePHP中的多个表中检索连接结果(使用cakePHP mvc架构)。例如,我有三个表要加入(tbl_topics,tbl_items,tbl_votes。他们的关系定义如下:一个主题可以有很多项目,一个项目可以有很多选票。现在我想检索一个主题列表,其中包括每个主题的所有项目的所有投票。对此的SQL查询如下:
SELECT Topic.*, count(Vote.id) voteCount
FROM
tbl_topics AS Topic
LEFT OUTER JOIN tbl_items AS Item
ON (Topic.id = Item.topic_id)
LEFT OUTER JOIN tbl_votes AS Vote
ON (Item.id = Vote.item_id);
我的问题是我可以使用$this-><Model Name>->query
函数轻松完成,但这需要在我不想要的控制器中编写sql代码。我正在尝试找出其他任何方法(例如find()
)。
答案 0 :(得分:40)
$markers = $this->Marker->find('all', array('joins' => array(
array(
'table' => 'markers_tags',
'alias' => 'MarkersTag',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('MarkersTag.marker_id = Marker.id')
),
array(
'table' => 'tags',
'alias' => 'Tag',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array(
'Tag.id = MarkersTag.tag_id',
'Tag.tag' => explode(' ', $this->params['url']['q'])
)
)
)));
在nate abele的文章中提到:link text
答案 1 :(得分:2)
我会诚实地说,如果你只是在你的模型中创建一个函数,比如getTopicVotes()和在那里调用query(),你可能会更开心。我能想到的每一个其他解决方案只会让它更复杂,因此更加丑陋。
编辑:
根据您的数据大小,并假设您已正确设置模型关系(主题包含多个项目有多个投票),您可以执行包含所有的简单查找('all')项目和投票,然后做这样的事情:
foreach ($this->data as &$topic)
{
$votes = Set::extract('/Topic/Item/Vote', $topic);
$topic['Topic']['vote_count'] = count($votes);
}
这里有两件事很重要:
答案 2 :(得分:2)
您可以在find()查询中轻松设置“递归”属性。
$result = $this->Topic->find('all', array('recursive' => 2));
或者,您可以在模型中使用Containable行为。然后你可以使用:
$this->Topic->contain(array(
'Item',
'Item.Vote',
));
$result = $this->Topic->find('all');
或
$result = $this->Topic->find('all', array(
'contain' => array(
'Item',
'Item.Vote',
),
));
答案 3 :(得分:1)
您需要的是递归关联支持,目前使用CakePHP库存是不可能的 虽然可以使用一些bindModel trickery来实现 或实验RecursiveAssociationBehavior。
这两种解决方案都要求您使用额外的代码或依赖应用程序中的行为,但如果您不耐写编写纯SQL代码的诱惑,您将获得能够使用Cake的分页奖励,自动条件,模型魔术等。
答案 4 :(得分:0)
我认为这个答案已经提交了,但是我在这里发给那些仍在寻找答案的人。 可以使用如下的find()方法完成连接
$result = $this->ModelName1->find("all",array(
'fields' => array('ModelName1.field_name','Table2.field_names'), // retrieving fileds
'joins' => array( // join array
array(
'table' => 'table_name',
'alias' => 'Table2',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('ModelName1.id = Table2.id') // joins conditions array
),
array(
'table' => 'table_name3',
'alias' => 'Table3',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('Table3.id = Table2.id')
)
)));
答案 5 :(得分:-2)
你应该学习HaBTM(已经和属于许多人) http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html