我有3个模型
- 用户
- 渠道
- 回复
模型关系
user
有belongsToMany('App\Channel');
channel
有hasMany('App\Reply', 'channel_id', 'id')->oldest();
假设我有 2 个频道 - 频道 1 - 频道 2
channel-2
最新回复比 channel-1
现在,我想通过其频道的当前回复来订购用户的频道。就像一些聊天应用程序。我怎样才能像这样订购用户的频道?
- 频道2
- 通道1
我已经尝试了一些代码。但什么也没发生
// User Model
public function channels()
{
return $this->belongsToMany('App\Channel', 'channel_user')
->withPivot('is_approved')
->with(['replies'])
->orderBy('replies.created_at'); // error
}
// also
public function channels()
{
return $this->belongsToMany('App\Channel', 'channel_user')
->withPivot('is_approved')
->with(['replies' => function($qry) {
$qry->latest();
}]);
}
// but i did not get the expected result
编辑 也,我试过这个。是的,我确实得到了预期的结果,但如果没有回复,它不会加载所有频道。
public function channels()
{
return $this->belongsToMany('App\Channel')
->withPivot('is_approved')
->join('replies', 'replies.channel_id', '=', 'channels.id')
->groupBy('replies.channel_id')
->orderBy('replies.created_at', 'ASC');
}
编辑:
原文由 Hitori 发布,翻译遵循 CC BY-SA 4.0 许可协议
据我所知, 急切加载
with
方法运行第二个查询。这就是为什么你无法通过预 加载with
方法实现你想要的。我认为使用
join
方法结合 关系方法 是解决方案。以下解决方案已经过全面测试并且运行良好。然后你可以调用
$user->sortedChannels('desc')
来获取按回复排序的 频道 列表created_at
属性。对于像 频道 这样的条件(可能有也可能没有回复),只需使用
leftJoin
方法。编辑:
如果你想在查询中添加
groupBy
方法,你必须特别注意你的orderBy
子句。因为在 SQL 性质中,Group By
子句先于Order By
子句运行。请参阅 此 stackoverflow 问题 中的详细信息。因此,如果您添加
groupBy
方法,则必须使用orderByRaw
方法,并且应该像下面这样实现。