今回扱うテーマはデータ間の多対多の関係で2つのテーブルをつなぐ中間データが持つ情報も取得したいということを考えます。
まず、講師一覧を表すteacherというテーブルがあります。とりあえず、idとnameを持つとします。
id name
1 鈴木
2 佐藤
3 田中
4 山田
次に、教える科目を表すsubjectというテーブルがあります。こちらも簡単に考えるため、idとsubject_nameのみを持っているとします。
id subject_name
1 英語
2 数学
3 国語
4 社会
5 理科
さらに、講師は複数の科目を担当できるものとします。ただし、メインで教える科目とサブで教える科目は区別します。
そして、teacherとsubjectを結ぶteacher_subjectというテーブルがあります。これはteacher_id、subject_idに加えてメイン、サブを区別するtypeというカラムがあります(メインなら1、サブなら2)。
teacher_id subject_id type
1 1 1
1 4 2
2 2 1
2 5 2
3 3 1
4 4 1
4 3 2
ここで、こんな表を作りたいとします。
講師 科目 種類
鈴木 英語 メイン
鈴木 社会 サブ
佐藤 数学 メイン
佐藤 理科 サブ
田中 国語 メイン
山田 社会 メイン
山田 国語 サブ
このとき、モデルクラスTeacher.php, Subject.phpに加えてTeacherSubject.phpをそれぞれ以下の様に用意します。
app\Teacher.php
<?php namespace App; use Illluminate\Database\Eloquent\Model; class Teacher extends Model { protected $fillable = [ 'name' ]; protected $table = "teacher"; public function subjects() { return $this->belongsToMany('App\Subject', 'teacher_subject', 'teacher_id', 'subject_id') ->using('App\TeacherSubject') ->withPivot('type'); } }
app\Subject.php
<?php namespace App; use Illluminate\Database\Eloquent\Model; class Subject extends Model { protected $fillable = [ 'subject_name' ]; protected $table = "subject"; public function teachers() { return $this->belongsToMany('App\Subject', 'teacher_subject', 'subject_id', 'teacher_id') ->using('App\TeacherSubject') ->withPivot('type'); } }
app\TeacherSubject.php
<?php namespace App; use Illuminate\Database\Eloquent\Relations\Pivot; class TeacherCountry extends Pivot { protected $table = "teacher_subject"; }
こんな感じでwithPivotを使うことで中間テーブルの情報を取得することができます。中間テーブルのモデルクラスはIlluminate\Database\Eloquent\Relations\Pivotを継承して作ります。
また、ある講師に対してメインの科目だけ欲しい場合は
public function main_subjects() { return $this->belongsToMany('App\Subject', 'teacher_subject', 'teacher_id', 'subject_id') ->using('App\TeacherSubject') ->wherePivot('type', 1); }
という風にwherePivotで絞り込むことができます。
Eloquentのリレーションは結構奥が深いので、是非ともしっかりとマスターしたいですね。