Day 3・ルーティングとコントローラー、ルートモデルバインディング
ルートモデルバインディング
URLのIDから、対応するモデルを自動で取り出す仕組み。定型のfindOrFailを消せる。
毎回書いていた「探して、無ければ404」
詳細画面や更新処理では、まず「URLのIDに対応するデータをDBから探し、無ければ404を返す」という決まり文句を書きます。この定型コードが全アクションに散らばると、書くのも読むのも面倒です。
public function show($id)
{
// IDでDBを探し、見つからなければ自動で404を投げる
$post = Post::findOrFail($id);
return view('posts.show', ['post' => $post]);
}ルートモデルバインディングとは
は、URLに含まれるIDから対応するモデルをLaravelが自動で取り出して、コントローラのメソッドに渡してくれる仕組みです。メソッドの引数に「型」を書いておくだけで、findOrFail相当の処理をフレームワークが肩代わりしてくれます。
// ルート: /posts/{post} の {post} 部分がキー
Route::get('/posts/{post}', [PostController::class, 'show']);
public function show(Post $post) // 引数の型が Post なら…
{
// URLのIDから対応する Post が自動で見つかり、無ければ404
// findOrFail はもう書かなくてよい
return view('posts.show', ['post' => $post]);
}なぜこれが便利なのか
「探して、無ければ404」という定型コードを全アクションから消せます。コントローラの本文が「本当にやりたいこと」だけになり、意図が読みやすくなります。また404の返し方がフレームワークで統一されるので、ある画面だけ404にならない、といった抜け漏れも防げます。定型を減らして間違いの起きる余地を減らす、という設計上のメリットです。
暗黙のバインディングと明示のバインディング
デフォルトでは主キー(通常はid)で検索されます。これが「暗黙のバインディング」です。一方、URLをIDではなく人間に読みやすいスラッグ(例: /posts/laravel-basics)にしたい場合は、どのカラムで探すかを指定する「明示のバインディング」を使います。
// ルート側で {post:slug} と書くと、id ではなく slug 列で検索される
Route::get('/posts/{post:slug}', [PostController::class, 'show']);
// あるいはモデル側で既定の解決キーを指定する方法もある
class Post extends Model
{
public function getRouteKeyName(): string
{
return 'slug';
}
}落とし穴
バインディングは便利ですが「見つからなければ勝手に404」になる点は覚えておきましょう。ソフトデリート()されたデータは既定では見つからず404になります。削除済みも含めて扱いたい場合は、明示的にその指定が必要です。魔法ではなく、裏でfindOrFail相当が動いていると理解しておくのが大切です。
面接ではこう言う
「ルートモデルバインディングは、URLのIDから対応するモデルを自動解決して渡してくれる仕組みです。findOrFailのような定型コードを消せるので、コントローラが本来の処理だけになり読みやすくなります。裏では見つからなければ404が返る、という挙動を理解した上で使っています。スラッグで解決したいときは明示バインディングを使います」と説明できます。
読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。
理解度チェック
答えられれば、面接で説明できる状態に一歩近づきます。
ルートモデルバインディングが「便利」とされる主な理由はどれか。
URLをIDではなくスラッグ(例: /posts/laravel-basics)で解決させたい。適切な方法はどれか。
ルートモデルバインディングを使うとコードがどう変わるか、findOrFailに触れながら説明せよ。
記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。