怎么在whereHas里面orderBy?

目前我有个查询:

$likes = Topic::whereHas('likes', function (Builder $query) use ($user) {
            $query->where('user_id', $user->id);
        })->with('user')->orderBy('created_at', 'desc')->paginate(6);

我靠likes表的里topic_id和user_id,查出某个用户点赞了哪些文章,我加了一个orderBy想要实现,最近点赞的文章排列在最前面,但是这个查出来的是以Topic的发布时间排序的,怎么以likes的创建时间排序呢?

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 9
$likes = Topic::whereHas('likes', function (Builder $query) use ($user) {
            $query->where('user_id', $user->id)->orderByDesc('你的排序字段');
        })->with('user')->orderBy('created_at', 'desc')->paginate(6);
2周前 评论
wongvio (楼主) 2周前
浪里小白龙 (作者) 2周前
wongvio (楼主) 1周前
浪里小白龙 (作者) 1周前

如果你的likes表model名叫Likes,通过Likes.topic_id关联到Topic.id的话,以下代码可以试一下。 不是我猜的这样的话,你自己看着改。

$likes = Topic::whereHas('likes', function (Builder $query) use ($user) {
            $query->where('user_id', $user->id);
        })->with('user')->orderBy(
            Likes::select('created_at')->whereColumn('likes.topic_id', 'topic.id'), 'desc'
        )->paginate(6);
1周前 评论

可以在 你 模型关联 likes 的地方直接orderBy(你的排序字段)

1周前 评论

orderBy 根据 with 关联中的字段来进行排序的,排序的实现是以子查询的方式来的;数据量一大就会比较慢,不建议这么使用;如果不考虑性能,写法非常方便简洁;

直接贴代码,首先注册 Illuminate\Database\Eloquent\Builder 宏:

Builder::macro('orderByWith', function ($relation, $column, $direction = 'asc'){
    /** @var Builder $this */
    if (is_string($relation)) {
        $relation = $this->getRelationWithoutConstraints($relation);
    }

    return $this->orderBy(
        $relation->getRelationExistenceQuery(
            $relation->getRelated()->newQueryWithoutRelationships(),
            $this,
            $column
        ),
        $direction
   );
});

然后就可以直接使用了

Topic::where(...)->orderByWith('likes','created_at','desc')->get();

PS:laravel7 + 以上使用, 低版本没有试过

1周前 评论

在whereHas 中的排序只影响关联模型的顺序,不会影响到Topic主表的顺序,有两种思路:

  • 使用left join 手动关联,然后按照点赞时间排序
  • 以likes表为主表,关联topic表,按照点赞时间排序, 处理下返回结果
1周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!