Laravel如何获取最新10条评论且每个用户仅一条(Eloquent实现)
嘿,这个需求用Eloquent完全可以做到简洁优雅,我给你分享两种实用的方案,都是社区里比较认可的写法:
实现方案
方法一:子查询筛选(兼容大多数Laravel版本)
核心思路是先定位每个用户最新的那条评论ID,再基于这些ID获取完整评论数据,最后取最新的10条。
假设你的评论表是comments,包含id、user_id、created_at等字段,代码如下:
$latestComments = Comment::query() ->whereIn('id', function ($subquery) { // 子查询:按用户分组,取每个用户最新的评论ID(这里用ID自增特性,最大ID即最新) $subquery->select(DB::raw('MAX(id)')) ->from('comments') ->groupBy('user_id'); }) ->orderBy('created_at', 'desc') ->take(10) ->get();
如果你的评论不是靠ID判断新旧,而是严格依赖created_at字段,可以把查询调整为:
$latestComments = Comment::query() ->whereIn('id', function ($subquery) { $subquery->select('id') ->from('comments as c2') ->whereColumn('c2.user_id', 'comments.user_id') ->orderBy('c2.created_at', 'desc') ->limit(1); }) ->orderBy('created_at', 'desc') ->take(10) ->get();
方法二:用latestOfMany关联(Laravel 8.42+)
如果你的Laravel版本在8.42及以上,推荐用这种更贴合Eloquent风格的写法。
首先在User模型里定义一个关联,直接指向该用户的最新评论:
// app/Models/User.php public function latestComment() { return $this->hasOne(Comment::class)->latestOfMany(); }
然后就可以通过用户模型关联查询,获取每个用户的最新评论,再筛选出最新的10条:
$latestComments = User::query() ->with('latestComment') ->has('latestComment') // 确保只取有评论的用户 ->orderByDesc('latest_comment.created_at') ->take(10) ->pluck('latestComment') // 提取评论数据 ->filter(); // 过滤掉可能的空值(可选,has已经做了保障)
这种方法代码可读性更强,完全遵循Eloquent的关联设计理念,非常优雅。
小提示
- 如果你的评论表开启了软删除,记得在查询中加上
->withTrashed()(如果需要包含已删除评论)或者确保查询默认只取未删除的记录。 - 两种方法都能保证每个用户仅显示一条评论,且最终结果是按时间排序的最新10条。
内容的提问来源于stack exchange,提问作者Mahdi Majidzadeh
相关产品推荐
相关产品推荐

