2
votes

Laravel: commande éloquente par colonne de relation hasOne en utilisant avec

J'ai un modèle Commandes avec une relation hasOne participant.

return $orders->sortBy('participant.last_name');

Je dois récupérer la collection Commandes triées par participant.last_name

Mon approche

$orders = \App\Orders::with(['participant',])
              ->where('user_id', $user->id)  
              ->orderBy('participant.last_name')
              ->get();

Échec avec:

Table non définie: 7 ERREUR: entrée de clause FROM manquante pour la table \ "participant \" \ nLINE 1: ... 1

J'ai essayé de le trier après la collecte

public function participant()
{
    return $this->hasOne('App\OrderParticipant', 'order_id');
}

Mais cela ne trie pas du tout

BTW je suis en utilisant postgres

Merci.


0 commentaires

3 Réponses :


8
votes

Vous ne pouvez pas commander directement par hasOne, vous devez utiliser join

$orders = \App\Orders::with([
                'participant',                    
                ])
            ->where('orders.user_id', $user->id)  
            ->join('participants', 'orders.user_id', '=', 'participants.id')
            ->orderBy('participants.last_name')
            ->select('orders.*','participants.id','participants.last_name')
            ->get();



4 commentaires

oh j'ai tout compris. J'ai dû utiliser select ('orders. *') Pour utiliser join


Oui maintenant cela semble correct, nous l'avons fait! Merci mon pote


Merci pour le conseil. Juste une question: quel est l'intérêt d'utiliser ici? N'est-ce pas redondant puisque nous utilisons déjà une jointure?


Vous êtes les bienvenus, car nous ne sélectionnons que l'identifiant et le nom, pas toutes les données des participants, et il est préférable de continuer à utiliser un moyen standard unique d'accéder aux données, à savoir les relations éloquentes pour maintenir un code propre et prévisible, mais vous pouvez faire tout ce que vous voulez. vous pensez que c'est mieux selon votre cas.



0
votes

Cela semble un peu redondant, mais je l'ai trié en utilisant join . Un assez laid cependant. Notez la partie select . Sans que tout soit foiré

          $orders = \App\Orders::select('orders.*')
                ->with([
                    '....',
                    'participant',
                    'participant.documents',
                    'participant.participantParent',
                    'participant.country',
                    '...'
                    ])
                ->join('order_participants', function ($join) {
                    $join->on('order_participants.order_id', '=', 'orders.id');
                })
                ->where('orders.user_id', $user->id)  
                ->where(function($q) {
                    $q->where('orders.status', '!=', 'completed')
                    ->orWhereNull('orders.status');
                })   
                ->orderBy('order_participants.last_name')
                ->orderBy('order_participants.first_name')
                ->get();

Comme ma requête est un peu plus compliquée que dans la question ci-dessus, je poste le code entier à titre d'exemple. Si je comprends bien, join doit venir avant where les déclarations


0 commentaires

2
votes

Vous pouvez y parvenir en

  //  eager loading
  $orders = \App\Orders::with(['participant'=> function($q){
             $q->orderBy('last_name', 'asc/desc');
            }
           ])->get();


1 commentaires

Est-ce que ce genre de relation "hasMany" uniquement enfant? mais cela ne triera pas la collection parent. Et participant est la relation "hasOne", qui n'a pas besoin d'être triée, car son seul ou nul