Laravel 5 关联关系加载及多讲师课程模型关联问题咨询
Laravel 5关联加载与多讲师课程方案
嘿,我来帮你搞定Laravel里的关联加载问题,顺便针对你那4天课程的讲师关联场景调整下模型设计~
一、当前模型关联的问题
你现在定义的Course和Instructor是一对多关联(一个讲师对应多门课程),但你的实际需求是一门4天课程每天对应不同讲师,这意味着一门课程需要关联多个讲师,当前的belongsTo关联只能绑定一个讲师,显然满足不了需求,得调整下模型设计。
二、两种适配多讲师场景的关联方案
方案1:固定天数的直接关联(适合4天固定场景)
如果课程天数确定是4天,最直接的方式是在courses表中添加instructor_day_1_id、instructor_day_2_id、instructor_day_3_id、instructor_day_4_id这几个外键字段,然后在Course模型里定义多个belongsTo关联:
// App\Course.php public function instructorDay1() { // 第二个参数指定关联的外键字段 return $this->belongsTo('App\Instructor', 'instructor_day_1_id'); } public function instructorDay2() { return $this->belongsTo('App\Instructor', 'instructor_day_2_id'); } // 同理添加instructorDay3、instructorDay4的关联方法
控制器@show方法中加载关联
要避免N+1查询问题,推荐用with()预加载关联:
// 只加载第1天的讲师 $course = Course::with('instructorDay1')->find($id); // 同时加载第1、2天的讲师 $course = Course::with(['instructorDay1', 'instructorDay2'])->find($id);
然后在视图里就能直接访问讲师信息:
// 输出第1天讲师的名称 echo $course->instructorDay1->name;
方案2:中间表多对多关联(适合天数灵活的场景)
如果以后课程天数可能调整,用中间表的多对多关联更灵活。先创建course_instructors中间表,结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | 主键 | 自增ID |
| course_id | 整数 | 关联courses表的外键 |
| instructor_id | 整数 | 关联instructors表的外键 |
| day | 整数 | 标记是课程的第几天(1-4) |
然后调整两个模型的关联:
// App\Course.php public function instructors() { return $this->belongsToMany('App\Instructor', 'course_instructors') ->withPivot('day') // 携带中间表的day字段 ->orderBy('day'); // 按天数排序,方便获取顺序 } // App\Instructor.php public function courses() { return $this->belongsToMany('App\Course', 'course_instructors') ->withPivot('day'); }
控制器@show方法中加载关联
// 加载该课程所有关联的讲师及对应天数 $course = Course::with('instructors')->find($id); // 只加载第1天的讲师 $course = Course::with(['instructors' => function ($query) { $query->wherePivot('day', 1); }])->find($id);
访问第1天讲师的方式:
// 从关联集合中筛选出第1天的讲师 $day1Instructor = $course->instructors->where('pivot.day', 1)->first(); if ($day1Instructor) { echo $day1Instructor->name; }
三、关联加载的小补充
- 预加载(
with()):适合在查询课程之前就确定要加载的关联,能有效避免N+1查询问题,批量查询课程时一定要用。 - 延迟加载(
load()):如果已经拿到了课程实例,之后再需要加载关联,可以用这个方法:
$course = Course::find($id); // 延迟加载第1天的讲师 $course->load('instructorDay1');
内容的提问来源于stack exchange,提问作者maximus1127
相关产品推荐
相关产品推荐

