Éloquent avec imbriqué whereHas
Actuellement, j'ai cette whereHas dans une collection de mon modèle:
$query = self::whereHas('club', function($q) use ($search)
{
$q->whereHas('owner', function($q) use ($search)
{
$q->where('name', 'LIKE', '%'. $search .'%');
});
});
J'étais sous l'impression que le code ci-dessus peut être en tant que tel:
$query = self::whereHas('club.owner', function($q) use ($search)
{
$q->where('name', 'LIKE', '%'. $search .'%');
});
Je suis conscient que c'est déjà beaucoup de pouvoir, mais même alors, si j'ai une relation imbriquée 5 niveaux de profondeur, les choses vont devenir laid.
Mise à jour:
Comme indiqué dans les commentaires, j'ai fini par ne pas faire de ma question claire, je m'en excuse.
Je vais essayer d'utiliser un exemple simple, considérons $owner->club->membership->product->package
, maintenant, de propriétaires, je recherche un certain paquet, il serait quelque chose comme ceci:
$query = self::whereHas('club', function($q) use ($search)
{
$q->whereHas('membership', function($q) use ($search)
{
$q->whereHas('product', function($q) use ($search)
{
$q->whereHas('package', function($q) use ($search)
{
$q->where('alias', 'LIKE', '%'. $search .'%');
});//package
});//product
});//membership
});//club
Est-ce correct? Est-il un raccourci?
- Quel est le problème et ce que vous attendez?
- Si votre question est: pourquoi ne puis-je pas utiliser de club".propriétaire", comme le terrain?
- Parce que chaque niveau d'imbrication exécute une autre requête avec un where id IN () de la clause pour la relation imbriquée. Vous souhaitez rechercher tous les modèles associés avec COMME clause?
- J'ai mis à jour la question. @deczo Est-il possible de faire ce que vous dites? Ici, je suis juste en train de chercher dans un seul modèle. Mais si je voulais faire comme vous le dites?
- ce sera résultat en plusieurs sous-requêtes EXISTENT(), mauvaise idée.
- Il suffit de lire la accepté de répondre.
Vous devez vous connecter pour publier un commentaire.
Mise à jour: le PR a été fusionné à la version 4.2, il est possible d'utiliser point imbriquées notation dans
has
méthodes (->has('relation1.relation2)
->whereHas('relation1.relation2, ..
)Votre question est un peu floue ou vous ne comprenez pas whereHas() méthode telle qu'elle est utilisée pour filtrer les modèles (les utilisateurs dans ce cas) et ne conserver que celles qui sont liées à des modèles de montage des conditions de recherche.
Il semble que vous voulez trouver Paquets le contexte d'une Utilisateur, donc pas besoin d'utiliser whereHas méthode.
De toute façon, selon les relations (1-1,1-m,m-m), ce peut être facile ou assez dur et pas très efficace. Comme je l'ai dit, le chargement imbriqués les relations signifie que pour chaque niveau d'imbrication vient une autre base de données de la requête, de sorte que dans ce cas vous vous retrouvez avec 5 requêtes.
Indépendamment des relations que vous pouvez inverser cette chaîne, car il sera plus facile:
edit: Ce n'est pas d'aller travailler atm comme whereHas() n'a pas de processus de dot imbriqués les relations!
Comme vous pouvez le voir c'est beaucoup plus lisible, toujours à court de 5 requêtes.
Aussi de cette façon, vous obtenez les paquets, ce qui est une Collection unique de modèles que vous vouliez.
Alors que le contexte d'un utilisateur, vous devez obtenir quelque chose comme ceci (selon les relations qui existent encore):
Vous obtenez le point, n'est-ce pas?
Vous pouvez récupérer les paquets provenant de la Collection, mais il serait gênant. Il est plus facile dans l'autre sens.
Donc la réponse à votre question serait tout simplement joindre les tables:
Bien sûr, vous pouvez l'envelopper dans une belle méthode de sorte que vous n'avez pas à écrire ce chaque fois que vous effectuez ce type de recherche.
Les performances de cette requête sera certainement beaucoup mieux que de les séparer 5 requêtes indiqué ci-dessus. Évidemment, de cette façon, vous ne charger que les paquets, sans autres modèles.
whereHas()
ou pas? Parce que de ce que j'ai de l'expérience, il n'est pas..@dev
branche, pour qu'il n'y a pas eu de nouvelle version depuis encore.composer.json
pour s'assurer qu'il télécharge la version du framework qui inclut ce code?4.2.*@dev
optionwhereHas()
méthodes pour cela. Les géohelminthiases. comme:Model::whereHas('releation', function($q1){ $q1->whereHas('subRelation', function($q2){ $q2->where('...'); }); });
Il a travaillé, cependant comme vous pouvez le voir c'est très laid.