Comment trier un champ de tableau croisé dynamique de plusieurs-à-plusieurs relations dans Éloquent ORM
J'ai été en utilisant Éloquent ORM pour un certain temps maintenant, et je le sais très bien, mais je ne peux pas faire la suite, tandis que il est très facile à faire dans l'.
J'ai les utilisateurs avec un plusieurs-à-plusieurs chansons, table intermédiaire étant song_user (comme il convient). Je voudrais obtenir les meilleures chansons de l'utilisateur, à en juger par le nombre de lecture. Bien sûr, nombre de lecture est stocké dans la table intermédiaire.
Je peux le faire dans Fluent:
$songs = DB::table('songs')
->join('song_user', 'songs.id', '=', 'song_user.song_id')
->where('song_user.user_id', '=', $user->id)
->orderBy("song_user.play_count", "desc")
->get();
Facile. Mais je veux le faire dans Éloquent, qui, bien sûr, ne fonctionne pas:
$songs = Song::
with(array("song_user" => function($query) use ($user) {
$query->where("user_id", "=", $user->id)->orderBy("play_count", "desc");
}))
- Je n'ai pas de programme d'installation pour l'essayer, mais avez-vous essayé quelque chose comme
$songs = $usr->songs()->pivot()->order_by('play_count','desc')->songs();
? La Question est de savoir si vous pouvez "remonter" àsongs
après le tableau croisé dynamique, puisqu'il ne semble pas être un modèle normal. - Cela ne fonctionne pas, malheureusement.
- Eh bien, vous pouvez toujours faire le tableau croisé dynamique d'un modèle et de travail à travers cela. Vous ne devez configurer d'autres clés étrangères, de sorte que les entrées sont correctement supprimés lorsque leurs parents respectifs est.
- Je suis actuellement en train de le faire, mais en utilisant cette approche, vous perdez le filtrage automatique de l'utilisateur de chansons ($user->chansons()) et vous devez vous rappeler de le faire manuellement (
SongUser::where("user_id", "=", $user->id)->etc...
). - Pourquoi, c'est ce que les relations sont pour, au lieu d'un seul, plusieurs-à-plusieurs vous faire deux un-à-plusieurs relations avec le tableau croisé dynamique. Vous devriez juste ajouter quelque chose comme
$this->has_many('song_user')
Vous devez vous connecter pour publier un commentaire.
Vous ne savez pas si vous envisagez de passer à Laravel 4, mais voici un exemple Éloquent pour le tri par un pivot tables de champs:
withPivot
est comme l'éloquentwith
et ajouter leplay_count
champ de tableau croisé dynamique pour les autres touches, il comprend déjà. Tous les champs de tableau croisé dynamique sont préfixés avecpivot
dans les résultats, de sorte que vous pouvez faire référence directement dans leorderBy
.Je n'ai aucune idée de ce qu'il pourrait ressembler à Laravel 3, mais peut-être cela aidera à vous diriger dans la bonne direction.
Cheers!
Je viens de trouver quelque chose dans le guide de l'utilisateur, apparemment, vous avez besoin de la
avec()
méthode.De la Guide Utilisateur:
De sorte que vous pouvez ensuite utiliser quelque chose de semblable lors de la définition de votre relation:
Exemple
J'ai simplement utilisé pour vous assurer qu'il fonctionne...
Sortie
Note: Il n'est pas par hasard que, sans l'aide de
order_by()
le résultat apparaît trié dansascending
commande par leplaycount
. J'ai confirmé l'existence de ce moyen de tests (que je ne sais pas encore comment faire pour afficher les requêtes dans les tests unitaires), mais vous ne devriez probablement pas compter sur ce comportement.Toute méthode qui est disponible dans Fluent devrait également être disponible avec Éloquent. C'est peut-être ce que vous recherchez?
Je l'ai fait ( sur plusieurs versions ) simplement à l'aide de la relation de la méthode que vous avez. J'utilise souvent un "ordre" de la colonne dans le tableau croisé dynamique, puis faire quelque chose comme cela.
Cela peut être ambiguë si vous avez des colonnes nommées "ordre" dans l'assemblage de la table. Si donc, vous devez spécifier ->order_by( 'article_tag.la commande' ). Et oui, vous avez besoin d'utiliser ->with() pour obtenir cette colonne dans le jeu de résultats. Comme simplement une question de style, je laisse la avec() de la relation de la méthode et juste retour de la vanille de l'objet de relation au lieu.
Dans votre Éloquent modèle, vous pouvez la chaîne de la orderBy colonne si vous incluez le nom de la table: