Reputation: 1451
I have two models: Contacts and Groups with belongsToMany association.
I want to get only that groups what is accessible for the contact. For this I have a custom finder.
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']]);
});
}
So I can call to following and I will get what I want.
$accessibleGroups = $this->Contacts->Groups->find('accessible', ['User.id' => $this->Auth->user('id')]);
But if I have a contain, than it will give back all groups not just accessible ones.
$contact = $this->Contacts->get($id, [
'contain' => ['Groups']
]);
How to limit the contain to accessible?
I can not add the custom finder to the table association definition's finder property, as I can not pass the $options there. Or can I?
Upvotes: 2
Views: 3999
Reputation: 60463
Let me quote the docs and the tests (if you can't find something in the docs, the tests are often a useful source for information on how to do things).
http://book.cakephp.org/3.0/en/orm/table-objects.html#passing-conditions-to-contain
If you have defined some custom finder methods in your associated table, you can use them inside 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'); } ]);
In that scenario you could simply pass in the conditions in the find()
call just like you are already doing.
http://book.cakephp.org/3.0/en/orm/table-objects.html#using-the-finder-option
So there's also this "hidden" finder
option that can be used instead of a callable:
$table->find('all')
->where(['Articles.author_id' => $authorId])
->contain([
'Authors' => [
'finder' => ['byAuthor' => ['author_id' => $authorId]]
]
]);
I guess it wouldn't hurt if the finder usage would be documented a little more detailed in the Cookbook, the docblock for Query::contain()
is missing info about it too.
Upvotes: 6