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

Laravel中如何在ClassMeet模型定义多层关联获取Subject表科目名称

实现方案

你的三张表关联逻辑为:class_meets.routine_id → routines.id、routines.subject_id → subjects.id,以下两种方案都可以实现从ClassMeet出发查询关联Subject的需求:


方式1:嵌套关联(最常用,维护成本低)

先补全各模型的基础关联定义即可:

第一步:给Routine模型新增关联Subject的方法

class Routine extends Model
{
    use SoftDeletes;
    public $table = 'routines';
    protected $dates = ['created_at', 'updated_at', 'deleted_at'];
    protected $fillable = [
        'academic_year_id',
        'subject_id',
        'classes_id', // 注意:你现有代码这里少了逗号,会触发语法错误,记得补上
        'day',
        'start_time',
        'end_time',
    ];

    // 新增关联
    public function subject()
    {
        return $this->belongsTo(Subject::class);
    }
}

第二步:给ClassMeet模型新增关联Routine的方法

class ClassMeet extends Model
{
    use SoftDeletes;
    public $table = 'class_meets';
    protected $dates = ['created_at', 'updated_at', 'deleted_at', 'date'];
    protected $fillable = [
        'routine_id',
        'date'
    ];

    // 新增关联
    public function routine()
    {
        return $this->belongsTo(Routine::class);
    }
}

使用方法

查询时用嵌套预加载即可直接获取科目名称:

// 查询所有ClassMeet及关联的科目信息
$classMeets = ClassMeet::with('routine.subject')->get();

// 取值示例
foreach ($classMeets as $meet) {
    echo $meet->date; // class_meets自身字段
    echo $meet->routine->subject->subject_name; // 关联拿到的科目名称
}

方式2:直接定义hasOneThrough关联(无需嵌套调用)

如果不想每次都通过routine嵌套获取科目,可以直接在ClassMeet中定义跨表关联:

class ClassMeet extends Model
{
    use SoftDeletes;
    public $table = 'class_meets';
    protected $dates = ['created_at', 'updated_at', 'deleted_at', 'date'];
    protected $fillable = [
        'routine_id',
        'date'
    ];

    // 基础关联还是需要保留
    public function routine()
    {
        return $this->belongsTo(Routine::class);
    }

    // 新增直达Subject的关联
    public function subject()
    {
        return $this->hasOneThrough(
            Subject::class, // 最终要获取的目标模型
            Routine::class, // 中间模型
            'id', // 中间表routines的主键
            'id', // 目标表subjects的主键
            'routine_id', // 当前表class_meets关联中间表的外键
            'subject_id' // 中间表routines关联目标表的外键
        );
    }
}

使用方法

直接预加载subject关联即可:

$classMeets = ClassMeet::with('subject')->get();

// 直接取值
foreach ($classMeets as $meet) {
    echo $meet->date;
    echo $meet->subject->subject_name;
}

软删除适配说明

如果需要查询包含已软删除的Routine或Subject数据,在关联定义末尾加上->withTrashed()即可,示例:

// 关联时包含已软删除的Routine
return $this->belongsTo(Routine::class)->withTrashed();

内容的提问来源于stack exchange,提问作者Agus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:15:05