今回扱うテーマはデータ間の多対多の関係で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のリレーションは結構奥が深いので、是非ともしっかりとマスターしたいですね。
