はじめに
ルートモデル結合についての備忘録です。
Laravel 8.X
ルートモデル結合
ルートパラメータからモデルを取得するとき、コントローラでIDなどを受け取って、データベースクエリでモデルインスタンスを取得できる。
ただ、ルートとモデルを結合することでその手間を省けるらしい。
例えば、Userモデルがあり、以下のようなルート情報だとし、コントローラはこんな感じだとする。
Route::get('profile/{id}','UserController@index')
public function index ($id){
$user = User::find($id);
return view('profilePage', ['User' => $user]);
}
ただLaravelはルートモデル結合があるので、実際はコントローラはこれでも問題ない。
use App\Models\User;
public function index (User $id){ // <- Userクラスを指定するだけでデータクエリ要らず
return view('profilePage', ['User' => $id]);
}
暗黙の結合
上記のルートモデル結合は、モデルを読み込んだ上でコントローラの関数の引数にモデルクラスを指定するだけでできる。
パラメータをそのモデルのプライマリキーと判断し、自動的に該当するモデルインスタンスを関数に渡してくれる。
これを 暗黙の結合 というらしい。
明示的結合
ただこのモデルクラスを指定する手間もRouteServiceProviderで省くことはできる。
app/Providers/RouteServiceProvider.phpに以下の様な記述を追加する。
use App\Models\User;
public function boot()
{
Route::model('user', User::class); // <- userパラメータとUserモデルを結合
}
そうすると、「user」というルートパラメータはUserモデルと結合される。つまり以下の様な記述で処理が可能になる。
Route::get('profile/{user}','UserController@index') // <- userパラメータ
public function index ($user){ // <- Userの記述が要らなくなった
return view('profilePage', ['User' => $user]);
}
最後に
他にも、自動的に判断するキーのカラムをパラメータから定義で指定したりも可能だったりするらいい。
さらに、バリデーションも自動的に対応してくれる。
詳しくはドキュメント(ルートモデル結合) を参照してください。