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

Laravel 5.8中如何获取单条记录对应的关联模型数据

问题场景

现有三张数据表,关联关系如下:

  • months 表与 registration 表为一对多(one-to-many)关系
  • years 表与 registration 表为一对多(one-to-many)关系

表结构与模型定义

registrations表迁移代码

public function up()
{
    Schema::create('registrations', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->string('father_name');
        $table->string('contact1');
        $table->string('contact2')->nullable();
        $table->string('address')->nullable();
        $table->integer('amount');
        $table->integer('day');
        $table->unsignedInteger('month_id');
        $table->unsignedBigInteger('year_id');
        $table->timestamps();
    });
}

Registration模型代码

class Registration extends Model
{
    protected $fillable =
        ['name', 'father_name', 'contact1', 'contact2', 'address', 'amount',
            'day', 'month_id', 'year_id'
        ];

    public function month()
    {
        return $this->belongsTo(Month::class);
    }

    public function year()
    {
        return $this->belongsTo(Year::class);
    }
}

Month模型代码

class Month extends Model
{
    public function registration()
    {
        return $this->hasMany(Registration::class);
    }
}

Year模型代码

class Year extends Model
{
    public function registration()
    {
        return $this->hasMany(Registration::class);
    }
}

问题描述

需求为查询单条registration记录及其关联的month、year数据,控制器show方法原有代码如下:

public function show(Registration $reg)
{
    $registration = $reg::with('month', 'year')->get();
    return ['registration' => $registration];
}

执行上述代码后返回了全量registration记录,而非路由模型绑定注入的目标单条记录。测试发现直接通过模型名调用with方法可以正确获取带关联的全量记录,但对注入的单条模型实例使用with方法仍返回全量数据,不符合预期,需要实现仅获取当前单条registration实例关联的Month和Year数据的效果。

问题原因

返回全量数据的核心原因是:$reg::with(...)属于静态调用模型类的查询构造器方法,等价于直接写Registration::with(...),和传入的$reg实例没有任何关联,后续调用get()自然会查询全表返回所有记录。

解决方案

有两种常用实现方式,按需选择即可:

方案1:对已注入的模型实例加载关联(推荐)

路由模型绑定已经查询出单条$reg实例,此时不需要重新发起全表查询,直接调用load()方法加载当前实例的关联数据即可:

public function show(Registration $reg)
{
    // 加载当前实例关联的month和year数据
    $reg->load('month', 'year');
    return ['registration' => $reg];
}

load()是针对已存在的模型实例做懒惰预加载,只会加载当前这条记录对应的关联数据,不会额外查询全表,性能更优。

方案2:通过实例ID发起单条带关联的查询

如果需要重新走查询构造器获取带关联的单条记录,可以用传入实例的id做条件约束,调用find()获取单条结果:

public function show(Registration $reg)
{
    $registration = Registration::with('month', 'year')->find($reg->id);
    return ['registration' => $registration];
}

注意:该方式会多执行一次数据库查询,性能弱于方案1,非特殊场景优先选择方案1。


内容的提问来源于stack exchange,提问作者Abdul Raheem Ghani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:54:21