You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:32:44