我有三个模型,用户,评论和页面。
用户 有很多 评论,评论 属于 页
所有模型都使用containable
行为,默认为recursive -1
。
如果我在评论上调用find()
查询,并使用包含 Page 模型字段的包含请求,则会正确返回结果使用单个查询,自动将 Page 表加入用户。
如果我从用户模型(包含 评论和 Comment.Page )调用类似查询,结果是查询来源评论,然后是每条评论的查询,以获取相关的页面。
有没有办法配置模型来维持JOIN优化?我假设相关模型上的belongsTo声明( Comments )将跟随主机模型( Users )。
更新
我应该澄清,我的问题使用了我的实际案例研究的简化版本。虽然我需要的最小解决方案包括此初始模型 hasMany 模型 belongsTo 模型结构,我也在寻找一个或多个 belongsTo 模型链的解决方案(我虽然会自动使用LEFT JOIN,因为这是可行的)。
答案 0 :(得分:2)
嗯那很有意思。这是一种应该在核心中实施的优化:)
无论如何,我认为你可以通过稍微不同的方式构建查询来获得相同的结果(可能格式不同):
$this->User->Comment->find('all', array(
'conditions' => array(
'Comment.user_id' => $userId
),
'contain' => array(
'User',
'Page'
)
));
通过从Comment模型中搜索,它应该使用两个左连接来连接数据,因为它们都是1:1关系。注意:结果数组可能与从用户模型搜索时的结果略有不同。
答案 1 :(得分:1)
您是否在询问是否有更简单的方法来包含所有查询?如果要包含当前控制器中的所有内容。您可以在beforeFilter()回调中执行包含,它将应用于该控制器中的所有查询。
答案 2 :(得分:1)
我不太确定我是否理解你的问题,但我认为你对于评论的许多sql调用有问题 - >页面链接?如果这是正确的,那么
希望有所帮助
编辑:我想到的一件事。您可以将关联数组中的连接类型更改为$this->Comment->myFindFct($params);
,这样可以将蛋糕单独调用相关模型
答案 3 :(得分:1)
我发现一个好方法是创建一个custom find method。
作为一个例子,我在你的用户模型中创建了一个名为_findUserComments()
的方法。然后,您将在此方法中执行所有连接,包含等。然后在您的控制器中,无论您需要获取所有用户的评论,都可以这样称呼它:
$this->User->find('UserComments', array(
"conditions" => array(
'User.id' => $userId
)
));
我希望这会有所帮助。
答案 4 :(得分:1)
如果模型定义如下:
代码贝娄将返回一个已加入的查询:
$this->loadModel('Comment');
$this->Comment->Behaviors->attach('Containable');
$queryResult = $this->Comment->find('all', array(
'contain' => array(
'User',
'Page'
)
));
下面的代码将返回两个查询。页面和用户加入一个查询,并在另一个查询中加入所有评论
$this->loadModel('Page');
$this->Page->Behaviors->attach('Containable');
$queryResult = $this->Page->find('all', array(
'contain' => array(
'User',
'Comment'
)
));
并且下面的代码将返回三个查询,每个模型一个:
$this->loadModel('User');
$this->User->Behaviors->attach('Containable');
$queryResult = $this->User->find('all', array(
'contain' => array(
'Page',
'Comment'
)
));