Comment filtrer par des conditions pour les modèles associés?
J'ai un belongsToMany association sur des Contacts et des Utilisateurs.
Je voudrais trouver les Contacts de l'Utilisateur.
J'aurais besoin de quelque chose comme
$this->Contacts->find()->contain(['Users' => ['Users.id' => 1]]);
Le livre parle de donner des conditions pour contenir, personnalisé finder méthodes et de chanter à travers l'association de la clé, mais je n'ai pas trouver la façon de les mettre ensemble.
OriginalL'auteur rrd | 2014-11-07
Vous devez vous connecter pour publier un commentaire.
Utiliser la Requête::correspondance (en) ou la Requête::innerJoinWith()
Lors de l'interrogation de la
Contacts
table, puis ce que vous cherchez estQuery::matching()
ouQuery::innerJoinWith()
, non pas (seulement)Query::contain()
.Voir livre de cuisine > Base de données Access & ORM > Query Builder > le Filtrage de Données Associées
Voici un exemple d'utilisation de vos tables:
Cela va automatiquement ajouter les joints + conditions de la requête générée, de sorte que les contacts sont en cours d'extraction qui sont associés à au moins un utilisateur avec l'id
1
.Cible de la table de jointure
Dans le cas où vous auriez un configurer manuellement plusieurs à plusieurs association via
hasMany
etbelongsTo
, vous pouvez cibler directement la table de jointure:Y compris les conteneurs
Dans le cas où vous voulez vraiment avoir toutes les associations retourné dans vos résultats trop, puis il suffit de garder à l'aide de
contain()
trop:Qui contient tous les utilisateurs qui appartiennent à un contact.
La restriction de conteneurs
Dans le cas où vous avez plusieurs matches, et vous en serais voulu de ne contenir que ces matchs, vous avez le filtre de l'enceinte de confinement. Dans cet exemple, il n'a pas beaucoup de sens car il ne serait que d'un match, mais dans d'autres cas, il pourrait être utile, par exemple si vous voulais pour correspondre à tous les contacts qui ont d'utilisateurs actifs, et de récupérer les contacts, y compris seulement les actifs associés aux utilisateurs:
Étant donné qu'il pourrait y avoir des doublons, c'est à dire plusieurs utilisateurs actifs pour un seul contact, vous aurez probablement envie de le groupe les choses en conséquence, afin d'éviter l'extraction de dupliquer les enregistrements de contact.
Profonde associations
Vous pouvez également cibler les associations plus profondes de cette façon, en utilisant le point noté chemin de la syntaxe connue de
Query::contain()
. Disons, par exemple, vous avez eu uneUsers hasOne Profiles
association, et que vous souhaitez associer uniquement pour les utilisateurs qui veulent recevoir des notifications, qui pourrait ressembler à quelque chose comme ceci:Cela va créer automatiquement tous les requis des jointures supplémentaires.
Sélectionnez à partir de l'autre table, au lieu
Avec ces associations et de vos exigences, vous pouvez également facilement requête à partir de l'autre côté, c'est à dire via le
Users
table et de les utiliser seulementQuery::contain()
à contenir les contacts, commeTous les contacts peuvent ensuite être trouvé dans les entités
contacts
propriété.Vous êtes les bienvenus, et vous pourriez être intéressé à la mise à jour...
Merci. Hier accidentellement, j'ai trouvé un autre moyen de faire ce que vous avez inclus dans la mise à jour. $this->Contacts->find()-> (['utilisateurs'])->correspondance('Users', function($q) { return $q->where(['Utilisateurs.id' => 1]); }); voir: github.com/cakephp/cakephp/issues/5109
Ah, j'aurais du le lire la question plus attentivement, sur un premier coup d'oeil j'ai pensé que les deux ne serait pas vous donner les résultats souhaités. Maintenant, quelqu'un a besoin de savoir si le boîtier truc est aussi fiable que le un peu plus "complexe" d'association de solution de contournement 🙂
Je reçois les résultats lorsque la condition est
return $q->where(['ContactsUsers.user_id IN' =>[1,2,3]]);
. S'il vous plaît laissez-moi savoir comment obtenir des résultats Uniques? Ou merci de répondre Ici stackoverflow.com/questions/46909779/... @ndmOriginalL'auteur ndm