Laravelのリレーション
Eloquentを用いることで、テーブルと対応するモデル間のリレーションを簡単に設定することができる。
リレーションのパターンは下記3種類。
- 一対一
- 一対多
- 多対多
パターンごとのリレーションの書き方
各モデルクラスにリレーションをメソッドとして定義する。
一対一
UserモデルがProfileモデルを1つ所有する →hasOne(Userモデルに定義)
public function profile(){
return $this->hasOne(Profile::class);
}
ProfileモデルがUserモデルに属する →belongsTo(Profileモデルに定義)
public function user(){
return $this->belongsTo(User::class);
}
※メソッドは利用するものだけを定義すればよい。
一対多
Userモデルが複数のPostモデルを所有する →hasMany(Userモデルに定義)
public function posts(){
return $this->hasMany(Post::class);
}
Postモデルが1つのUserモデルに属する →belongsTo(Postモデルに定義)
public function user(){
return $this->belongsTo(User::class);
}
多対多
Userモデルが複数のRoleモデルを所有する →belongsToMany(Userモデルに定義)
public function roles(){
return $this->belongsToMany(Role::class);
}
Roleモデルが複数のUserモデルを所有する →belongsToMany(Roleモデルに定義)
public function users(){
return $this->belongsToMany(User::class);
}
デフォルトの命名規則が適用されない場合(中間テーブル名や外部キーの命名が標準と異なる場合)は次のように明示的に定義する必要がある
※今回の場合であれば不要
Roleモデルが複数のUserモデルを所有する →belongsToMany(Roleモデルに定義)
//('関係するモデル', '中間テーブル', '中間テーブル外部キー', '中間テーブル外部キー(関係するモデル)');
public function users(){
return $this->belongsToMany(User::class, 'role_user', 'role_id', 'user_id');
}
リレーションを利用したデータ取得のサンプル
一対一のリレーション
IDが1のuserのprofileを取得
$user = User::find(1); // IDが1のUserを取得
$profile = $user->profile; // Userに関連するProfileを取得
一対多のリレーション
IDが1のUserの全てのPostのcontentを取得
$user = User::find(1);
$contents = $user->posts->pluck('content');
多対多のリレーション
"育成"を含むdescriptionのRoleを持つUserを全て取得
$users = User::whereHas('roles', function ($query) { // Userモデルに関連する Roleモデルの条件に基づいて Userを絞り込み
$query->where('description', 'like', '%育成%');
})->get();