自定义查找器与关联定义匹配?

rrd*_*rrd 2 cakephp-3.0

我有两个模型:联系人和具有belongsToMany关联的组.

我想只获得联系人可访问的组.为此,我有一个自定义查找器.

public function findAccessible(Query $query, array $options){
    return $query
            ->where(['admin_user_id' => $options['User.id']])
            ->orWhere(['public' => true])
            ->matching('Users', function($q) use ($options){
                return $q->orWhere(['Users.id' => $options['User.id']]);
            });
}
Run Code Online (Sandbox Code Playgroud)

所以我可以打电话跟随,我会得到我想要的.

$accessibleGroups = $this->Contacts->Groups->find('accessible', ['User.id' => $this->Auth->user('id')]);
Run Code Online (Sandbox Code Playgroud)

但是,如果我有一个包含,它将回馈所有组,而不仅仅是可访问的组.

$contact = $this->Contacts->get($id, [
        'contain' => ['Groups']
    ]);
Run Code Online (Sandbox Code Playgroud)

如何限制包含可访问?

我无法将自定义查找器添加到表关联定义的finder属性中,因为我无法在那里传递$ options.或者我可以吗?

ndm*_*ndm 6

让我引用文档和测试(如果您在文档中找不到某些内容,那么测试通常是有关如何执行操作的信息的有用来源).

http://book.cakephp.org/3.0/en/orm/table-objects.html#passing-conditions-to-contain

如果您在关联表中定义了一些自定义查找程序方法,则可以在包含内部使用它们:

// Bring all articles, but only bring the comments that are approved and
// popular.
$query = $articles->find()->contain([
    'Comments' => function ($q) {
       return $q->find('approved')->find('popular');
    }
]);
Run Code Online (Sandbox Code Playgroud)

在那种情况下,您可以简单地传递find()呼叫中的条件,就像您已经在做的那样.


http://book.cakephp.org/3.0/en/orm/table-objects.html#using-the-finder-option

https://github.com/cakephp/cakephp/blob/7fc4cfe3ae7d4c523331a44e2862bab5c8f44f1e/tests/TestCase/ORM/QueryTest.php#L2175

所以还有这个"隐藏" finder选项可以用来代替可调用的:

$table->find('all')
    ->where(['Articles.author_id' => $authorId])
    ->contain([
        'Authors' => [
            'finder' => ['byAuthor' => ['author_id' => $authorId]]
        ]
    ]);
Run Code Online (Sandbox Code Playgroud)

我想如果在Cookbook中更详细地记录查找程序的使用情况,也不会有什么问题,docblock for Query::contain()也缺少相关信息.