gpt4 book ai didi

php - Laravel Eloquent 按关系排序

转载 作者:IT王子 更新时间:2023-10-29 00:33:04 28 4
gpt4 key购买 nike

我有 3 个模型

  • 用户
  • channel
  • 回复

模型关系

  • user 拥有 belongsToMany('App\Channel');
  • channelhasMany('App\Reply', 'channel_id', 'id')->oldest();

假设我有 2 个 channel - channel 1- channel 2

channel-2 的回复比 channel-1

最新

现在,我想通过用户 channel 的当前回复来订购用户的 channel 。就像一些聊天应用程序一样。我怎样才能像这样订购用户的 channel ?

  • channel 2
  • channel 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

编辑另外,我试过这个。是的,我确实得到了预期的结果,但如果没有回复,它不会加载所有 channel 。

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');
}

编辑:

query result

最佳答案

据我所知,eager load with 方法运行第二个查询。这就是为什么您无法通过 eager loading with 方法实现您想要的。

我认为结合使用join 方法和relationship method 是解决方案。以下解决方案已经过全面测试并且运行良好。

// 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();
}

然后您可以调用 $user->sortedChannels('desc') 来获取按回复 created_at 属性排序的 channel 列表。

对于像 channels 这样的条件(可能有也可能没有回复),只需使用 leftJoin 方法。

public function sortedChannels($orderBy)
{
return $this->channels()
->leftJoin('replies', 'channel.id', '=', 'replies.channel_id')
->orderBy('replies.created_at', $orderBy)
->get();
}

编辑:

如果要在查询中添加groupBy 方法,则必须特别注意orderBy 子句。因为在 Sql 性质中,Group By 子句先于 Order By 子句运行。在 this stackoverflow question 查看此问题的详细信息.

因此,如果您添加 groupBy 方法,则必须使用 orderByRaw 方法,并且应该像下面这样实现。

return $this->channels()
->leftJoin('replies', 'channels.id', '=', 'replies.channel_id')
->groupBy(['channels.id'])
->orderByRaw('max(replies.created_at) desc')
->get();

关于php - Laravel Eloquent 按关系排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40837690/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com