Laravel 5.6 中三个模型的多对多关联关系实现方法咨询
实现 Laravel 5.6 中三个模型的多对多关联
嘿,你的场景是典型的三元多对多关联(多对多对多),通过中间表 teach 把 teachers、departments 和 subjects 三张表串了起来。下面我会逐个模型拆解关联定义,再给你几个实用的使用示例,帮你快速搞定这个需求。
1. Teacher 模型
打开 app/Teacher.php,添加和部门、科目关联的方法:
namespace App; use Illuminate\Database\Eloquent\Model; class Teacher extends Model { // 获取教师授课的所有部门(附带对应的科目信息) public function departments() { return $this->belongsToMany(Department::class, 'teach', 'id_teacher', 'id_department') ->withPivot('id_subject') // 带上中间表的科目ID,方便后续获取科目信息 ->withTimestamps(); // 如果你的teach表有时间戳字段,加上这个自动维护时间 } // 获取教师教授的所有科目(附带对应的部门信息) public function subjects() { return $this->belongsToMany(Subject::class, 'teach', 'id_teacher', 'id_subject') ->withPivot('id_department') // 带上中间表的部门ID ->withTimestamps(); } }
2. Department 模型
接着处理 app/Department.php,定义和教师、科目的关联:
namespace App; use Illuminate\Database\Eloquent\Model; class Department extends Model { // 获取部门下的所有授课教师(附带对应的科目) public function teachers() { return $this->belongsToMany(Teacher::class, 'teach', 'id_department', 'id_teacher') ->withPivot('id_subject') ->withTimestamps(); } // 获取部门开设的所有科目(附带授课教师) public function subjects() { return $this->belongsToMany(Subject::class, 'teach', 'id_department', 'id_subject') ->withPivot('id_teacher') ->withTimestamps(); } }
3. Subject 模型
最后是 app/Subject.php,添加和教师、部门的关联:
namespace App; use Illuminate\Database\Eloquent\Model; class Subject extends Model { // 获取教授该科目的所有教师(附带所属部门) public function teachers() { return $this->belongsToMany(Teacher::class, 'teach', 'id_subject', 'id_teacher') ->withPivot('id_department') ->withTimestamps(); } // 获取科目开设的所有部门(附带授课教师) public function departments() { return $this->belongsToMany(Department::class, 'teach', 'id_subject', 'id_department') ->withPivot('id_teacher') ->withTimestamps(); } }
实用关联操作示例
1. 查看某教师的所有授课记录(部门+科目)
$teacher = Teacher::find(1); // 通过departments关联遍历 foreach ($teacher->departments as $department) { $subject = Subject::find($department->pivot->id_subject); echo "在【{$department->name}】教授【{$subject->name}】<br>"; } // 或者通过subjects关联遍历 foreach ($teacher->subjects as $subject) { $department = Department::find($subject->pivot->id_department); echo "教授【{$subject->name}】,所属部门【{$department->name}】<br>"; }
2. 给教师添加一条新的教学记录
比如让ID为1的教师,在ID为2的部门教授ID为3的科目:
$teacher = Teacher::find(1); // 通过departments关联添加 $teacher->departments()->attach(2, ['id_subject' => 3]); // 或者通过subjects关联添加,效果一样 $teacher->subjects()->attach(3, ['id_department' => 2]);
3. 查看某部门的所有授课安排(教师+科目)
$department = Department::find(2); foreach ($department->teachers as $teacher) { $subject = Subject::find($teacher->pivot->id_subject); echo "教师【{$teacher->name}】教授【{$subject->name}】<br>"; }
小提醒
- 如果你的
teach表有自增主键id,Laravel 会自动识别,但三元关联里这个主键其实不是必须的,留着也不影响。 - 确保中间表的外键字段和关联定义里的参数对应上,我们已经明确指定了,所以不用担心命名约定的问题。
- 要是需要筛选关联结果,比如只获取某部门的数学老师,直接在关联后面链式加
where就行,比如$department->teachers()->where('subjects.id', 3)->get()(记得提前关联科目表哦)。
内容的提问来源于stack exchange,提问作者Othmane Boumediane
相关产品推荐
相关产品推荐

