À ma connaissance, charge ardente with
méthode exécuter la 2ème requête. C'est pourquoi vous ne pouvez pas obtenir ce que vous voulez avec le chargement rapide with
méthode.
Je pense utiliser join
méthode en combinaison avec la méthode relationnelle est la solution. La solution suivante a été entièrement testée et fonctionne bien.
// 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();
}
Ensuite, vous pouvez appeler $user->sortedChannels('desc')
pour obtenir la liste des chaînes trier par réponses created_at
attribut.
Pour des conditions telles que chaînes (qui peut ou non avoir des réponses), utilisez simplement leftJoin
méthode.
public function sortedChannels($orderBy)
{
return $this->channels()
->leftJoin('replies', 'channel.id', '=', 'replies.channel_id')
->orderBy('replies.created_at', $orderBy)
->get();
}
Modifier :
Si vous souhaitez ajouter groupBy
méthode à la requête, vous devez porter une attention particulière à votre orderBy
clause. Parce qu'en Sql nature, Group By
clause exécutée en premier avant Order By
clause. Voir le détail de ce problème sur cette question de débordement de pile
.
Donc, si vous ajoutez groupBy
méthode, vous devez utiliser orderByRaw
méthode et doit être implémenté comme suit.
return $this->channels()
->leftJoin('replies', 'channels.id', '=', 'replies.channel_id')
->groupBy(['channels.id'])
->orderByRaw('max(replies.created_at) desc')
->get();