According to my knowledge, eager load with
method run 2nd query. That's why you can't achieve what you want with eager loading with
method.
I think use join
method in combination with relationship method is the solution. The following solution is fully tested and work well.
// In User Model
public function channels()
{
return $this->belongsToMany('AppChannel', '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();
}
Then you can call $user->sortedChannels('desc')
to get the list of channels order by replies created_at
attribute.
For condition like channels (which may or may not have replies), just use leftJoin
method.
public function sortedChannels($orderBy)
{
return $this->channels()
->leftJoin('replies', 'channel.id', '=', 'replies.channel_id')
->orderBy('replies.created_at', $orderBy)
->get();
}
Edit:
If you want to add groupBy
method to the query, you have to pay special attention to your orderBy
clause. Because in Sql nature, Group By
clause run first before Order By
clause. See detail this problem at this stackoverflow question.
So if you add groupBy
method, you have to use orderByRaw
method and should be implemented like the following.
return $this->channels()
->leftJoin('replies', 'channels.id', '=', 'replies.channel_id')
->groupBy(['channels.id'])
->orderByRaw('max(replies.created_at) desc')
->get();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…