Laravel:如何在一对多关联中仅获取第一条关联记录?
嘿,这个需求我之前也碰到过,Laravel Eloquent确实有几种简洁的实现方式,给你分享下:
方法一:自定义专属关联(最推荐,复用性拉满)
直接在Post模型里新增一个专门返回第一条评论的关联方法,以后想用直接调用就行:
class Post extends Model { // 保留原来的一对多关联,不影响其他场景使用 public function comments() { return $this->hasMany(Comment::class); } // 新增:获取对应文章的第一条评论 public function firstComment() { // oldest()是按创建时间取最早的那条,要是想取最新的就换成latest() return $this->hasOne(Comment::class)->oldest(); } }
查询的时候就很简单了,直接加载这个新关联:
$posts = Post::with('firstComment')->get();
这样每个Post实例的firstComment属性就是对应的第一条评论模型(没有评论的话就是null),用起来特别顺手。
方法二:关联查询时直接加约束
如果不想新增模型方法,也可以在加载关联的时候直接给comments加筛选条件,只取第一条:
$posts = Post::with(['comments' => function ($query) { $query->oldest()->take(1); }])->get();
不过要注意,这种方式返回的comments还是一个集合(哪怕只有一条数据),如果你需要直接拿到单个评论对象,第一种方法会更合适。
方法三:子查询直接获取指定字段
要是你只需要第一条评论的某个字段(比如评论内容),不想加载完整的评论模型,可以用子查询把字段直接拼到文章结果里:
$posts = Post::select('posts.*') ->addSelect([ 'first_comment_content' => Comment::select('content') ->whereColumn('post_id', 'posts.id') ->oldest() ->limit(1) ]) ->get();
这样每个Post对象会多一个first_comment_content属性,直接拿到第一条评论的内容,适合列表展示这类场景。
另外提一句,你之前试的with('comments.0')这种写法是行不通的,因为with接受的是关联名称,不能直接用数组索引来筛选关联结果,所以才达不到预期效果~
内容的提问来源于stack exchange,提问作者kellymandem
相关产品推荐
相关产品推荐

