Secondo le mie conoscenze, carico desideroso with
metodo eseguire la seconda query. Ecco perché non puoi ottenere ciò che desideri con il caricamento ansioso with
metodo.
Penso di usare join
metodo in combinazione con metodo di relazione è la soluzione. La seguente soluzione è completamente testata e funziona bene.
// In User Model
public function channels()
{
return $this->belongsToMany('App\Channel', 'channel_user')
->withPivot('is_approved');
}
public function sortedChannels($orderBy)
{
return $this->channels()
->join('replies', 'replies.channel_id', '=', 'channel.id')
->orderBy('replies.created_at', $orderBy)
->get();
}
Quindi puoi chiamare $user->sortedChannels('desc')
per ottenere l'elenco dei canali ordina per risposte created_at
attributo.
Per condizioni come canali (che può avere o meno risposte), usa semplicemente leftJoin
metodo.
public function sortedChannels($orderBy)
{
return $this->channels()
->leftJoin('replies', 'channel.id', '=', 'replies.channel_id')
->orderBy('replies.created_at', $orderBy)
->get();
}
Modifica:
Se vuoi aggiungere groupBy
metodo alla query, devi prestare particolare attenzione al tuo orderBy
clausola. Perché in Sql natura, Group By
clausola eseguita prima di Order By
clausola. Vedi in dettaglio questo problema su questa domanda sull'overflow dello stack
.
Quindi se aggiungi groupBy
metodo, devi usare orderByRaw
metodo e dovrebbe essere implementato come il seguente.
return $this->channels()
->leftJoin('replies', 'channels.id', '=', 'replies.channel_id')
->groupBy(['channels.id'])
->orderByRaw('max(replies.created_at) desc')
->get();