如何在CakePHP中编写复杂的查找查询而不使用`$this->;型号->;query()`


How can I write a complex find query in CakePHP without using `$this->Model->query()`?

嘿,我希望有人有足够的Cake PHP经验来完成这项工作。

我正在做一个目前可以被亲切地称为推特克隆的东西。本质上,我有一个这样的设置。

用户有很多朋友。这是与用户表的多对多关系。它存储在一个名为friends_users的链接表中,列为user_id、friend_id。Users是一个列为user_id的表。

然后我有一个名为tips的表,它与用户相关联。用户可以有许多提示。

我想找到一种方法来查找Tip模型,该模型返回我传入的用户ID拥有的所有Tip以及该用户的任何朋友拥有的任何Tip。

此SQL查询运行良好-

SELECT *
FROM `tips`
JOIN users ON users.id = tips.user_id
JOIN friends_users ON tips.user_id = friends_users.friend_id
WHERE (friends_users.user_id =2 or tips.user_id=2)
LIMIT 0 , 30

这将返回用户#2的提示以及用户2的朋友的提示。

现在我如何使用$this->Tip->findxxxxx(user_id) 做同样的事情

我知道如果需要的话我可以使用Tip->query,但我正在努力学习。

如果查询结果中只需要一个提示列表,我很想在两个查询中做到这一点。第一个查找该用户及其朋友的用户ID列表,第二个查找属于这些ID中任何一个的提示。因此,在您的Tip模型中:

function findTipsByUserAndFriends($userId) {
  //FriendsUser is automagically created by CakePHP "with" association
  $conditions = array('FriendsUser.user_id'=>$userId);
  $fields = 'FriendsUser.friend_id';
  //get a list friend ids for the given user
  $friendIds = $this->Tip->User->FriendsUser->find('list', compact('conditions', 'fields'));
  //get list of all userIds for whom you want the tips
  $userIds = array($userId) + $friendIds;
  $conditions = array('Tip.user_id'=>$userIds);
  $tips = $this->Tip->find('all', compact('conditions'));
  return $tips;
}

请注意,您正在调用CakePHP用来为HABTM friends_users表建模的自动创建的"FriendsUser"模型上的第一个find,所以您不需要创建它

这是未经测试的,所以您可能需要调试其中的一些,但您已经明白了。

我建议您使用containable,它效果很好。

$aCond = array(
            'fields' => array(
                'Discount.*'
            ),
            'contain' => array(
                'Event' => array(
                    'conditions' => array('Event.id' => $iEventId)
                )
            )
        );
$aBulkDiscounts = $this->Discount->find('first', $aCond);

希望这能有所帮助。

在CakePHP中,多对多是"拥有并属于多"(HABTM)。假设你已经正确设置了关系,那么你需要做的是进行两级递归查找,这样你在上面找到的朋友就会检索到他们的所有朋友,这些朋友就会加载他们的提示。您可能必须动态绑定/取消绑定模型,以防止这些朋友获得他们的朋友(尽管在实践中这可能不是太大问题)。

必须阅读有关关联的手册条目。