如何根据相关模型的条件进行过滤? [英] How to filter by conditions for associated models?

查看:191
本文介绍了如何根据相关模型的条件进行过滤?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Users和Contacts上有一个belongsToMany关联。



我想找到给定用户的联系人。
我需要像

  $ this-> Contacts-> find() - > contains ['Users'=> ['Users.id'=> 1]]); 

菜单说明了包含,自定义finder方法的条件和通过关联键,


解决方案使用Query :: matching()或Query :: innerJoinWith()

联系人表查询时,您要查找的是 Query :: matching () Query :: innerJoinWith(),not(only) $ c>。



请参阅 食谱>数据库访问& ORM>查询生成器>按关联数据过滤



以下是使用表格的示例:

  $ this->联系人
- > find()
- > matching('Users',function(\Cake\ORM \Query $ q){
return $ q-> where(['Users.id'=> 1]);
});

这将自动添加所需的连接+条件到生成的查询。



包含安全壳



如果您真的想要在结果中返回所有关联,那么只需继续使用 contains()

  $ this->联系人
- > find ()
- >包含('Users')
- > match('Users',function(\Cake\ORM\Query $ q){
return $ q - > where(['Users.id'=> 1]);
});

这将包含属于某个联系人的所有用户。



如果你有多个匹配,并且你只想包含那些匹配,你也必须过滤容器。在这个例子中,它没有什么意义,因为只有一个匹配,但在其他情况下它可能是有用的,例如,如果你想匹配所有联系人有活动用户,并检索联系人,包括所有关联的活动用户:

  $ this->联系人
- > find()
- > contains(['Users'=> function(\Cake\ORM\Query $ q){
return $ q-> where(['Users.active'=> true]) ;
}])
- > match('Users',function(\Cake\ORM\Query $ q){
return $ q-> where Users.active'=> true]);
});



深层关联



更深的关联,通过使用从 Query :: contains()中已知的点标记路径语法,例如如果你也有一个 Users hasOne Xyz 关联,您可以按 Xyz.id 过滤

   - > matching('Users.Xyz',function(\Cake\ORM\Query $ q){
return $ q-> where(['Xyz.id'=> ; 1]);
})





使用这些关联和你的简单需求,你也可以从另一端轻松查询,即通过 Users 表, 查询:: contains()包含相关联系人,例如

  $ this->用户
- > find()
- >包含('联系人')
- >其中([
'Users.id'=> ; 1
])
- > first();

所有联系人都可以在实体联系人属性。


I have a belongsToMany association on Users and Contacts.

I would like to find the Contacts of the given User. I would need something like

$this->Contacts->find()->contain(['Users' => ['Users.id' => 1]]);

The cookbook speaks about giving conditions to contain, custom finder methods and sing through association key, but I did not find out how to put these together.

解决方案

Use Query::matching() or Query::innerJoinWith()

When querying from the Contacts table, then what you are looking for is Query::matching() or Query::innerJoinWith(), not (only) Query::contain().

See Cookbook > Database Access & ORM > Query Builder > Filtering by Associated Data

Here's an example using your tables:

$this->Contacts
    ->find()
    ->matching('Users', function(\Cake\ORM\Query $q) {
        return $q->where(['Users.id' => 1]);
    });

This will automatically add the required joins + conditions to the generated query.

Include containments

In case you actually want to have all the associations returned in your results too, then just keep using contain() too

$this->Contacts
    ->find()
    ->contain('Users')
    ->matching('Users', function(\Cake\ORM\Query $q) {
        return $q->where(['Users.id' => 1]);
    });

That would contain all users that belong to a contact.

In cases where you have multiple matches, and you'd wanted to contain only those matches, you'd have to filter the containment too. In this example it doesn't make much sense since there would be only one match, but in other situations it might be useful, say for example if you'd wanted to match all contacts that have active users, and retrieve the contacts including all the associated active users:

$this->Contacts
    ->find()
    ->contain(['Users' => function(\Cake\ORM\Query $q) {
        return $q->where(['Users.active' => true]);
    }])
    ->matching('Users', function(\Cake\ORM\Query $q) {
        return $q->where(['Users.active' => true]);
    });

Deep associations

You can also target deeper associations that way, by using the dot notated path syntax known from Query::contain(), for example if you also had a Users hasOne Xyz association, you could filter by Xyz.id using

->matching('Users.Xyz', function(\Cake\ORM\Query $q) {
    return $q->where(['Xyz.id' => 1]);
})

Select from the other table instead

With thse associations and your simple requirements, you could also easily query from the other side, ie via the Users table and use just Query::contain() to include the associated contacts, like

$this->Users
    ->find()
    ->contain('Contacts')
    ->where([
        'Users.id' => 1
    ])
    ->first();

All the contacts can then be found in the entities contacts property.

这篇关于如何根据相关模型的条件进行过滤?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆