如何使用CakePHP中的matching()查找具有公共父级的实体?

时间:2016-02-28 16:55:59

标签: php cakephp cakephp-3.x cakephp-3.2

我需要找到与给定文章列表具有相同作者的所有文章

这是我的自定义查找器方法:

public function findSimilar(Query $query, array $options)
    {
        if (empty($options['idList'])) {
            throw new Exception('idList is not populated');
        }
        // We are given a list of article IDs
        $idList = $options['idList'];

        return $query->matching('Authors', function ($q) use ($idList) {
            return $q->matching('Articles', function ($q2) use ($idList) {
                return $q2->where(['Articles.id IN' => $idList]);
            });
        });
    }

不幸的是我收到以下错误消息: PDOException:SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'Articles' 我做错了什么?

2 个答案:

答案 0 :(得分:6)

嵌套匹配存在很多限制,这可能是其中之一。我无法判断它是否是一个错误,因此您可能需要检查issues on GitHub并最终提交一个新的澄清。

来自文档的引用:

  

[...]点阵匹配路径应该用于嵌套的匹配()调用[...]

<强> Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Filtering by Associated Data

在任何一种情况下,使用点符号而不是嵌套应该可以解决问题,即

return $query->matching('Authors.Articles', function ($q) use ($idList) {
    return $q->where(['Articles.id IN' => $idList]);
});

如果你想在Authors上匹配,你可以叠加匹配器,比如

return $query
    ->matching('Authors', function ($q) {
        return $q->where(['Authors.foo' => 'bar']);
    })
    ->matching('Authors.Articles', function ($q) use ($idList) {
        return $q->where(['Articles.id IN' => $idList]);
    });

答案 1 :(得分:2)

如果是HasMany关系,我们可以通过以下方式轻松完成:

return $query->where([
   'Articles.author_id IN' => $this->find()
        ->select(['Articles.author_id'])
        ->where(['Articles.id IN' => $idList])
]);

//感谢CakePHP IRC频道上的jose_zap