#02 Laravel基礎

リソースルートとルートモデルバインディング

リソースルートとは

Webアプリには「一覧・詳細・作成フォーム・作成処理・編集フォーム・更新処理・削除」という7つの操作がほぼ必ず登場します。これを手書きすると7行のルート定義が必要ですが、Route::resource() を使うと1行で書けます。


Route::resource() の使い方

// 📁 routes/web.php

use App\Http\Controllers\PostController;

Route::resource('posts', PostController::class);

この1行が以下の7つのルートを自動で定義します。

HTTPメソッドURLコントローラーメソッドルート名
GET/postsindexposts.index
GET/posts/createcreateposts.create
POST/postsstoreposts.store
GET/posts/{post}showposts.show
GET/posts/{post}/editeditposts.edit
PUT/PATCH/posts/{post}updateposts.update
DELETE/posts/{post}destroyposts.destroy

リソースコントローラーを生成する

php artisan make:controller PostController --resource

--resource オプションをつけると、7つのメソッドが自動でスケルトン(骨格)として生成されます。

生成されたファイルを開いてみましょう。

<?php
// 📁 app/Http/Controllers/PostController.php(自動生成直後)

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()    { /* 一覧 */ }
    public function create()   { /* 作成フォーム */ }
    public function store()    { /* 作成処理 */ }
    public function show($post)  { /* 詳細 */ }
    public function edit($post)  { /* 編集フォーム */ }
    public function update(Request $request, $post) { /* 更新処理 */ }
    public function destroy($post) { /* 削除処理 */ }
}

ルートモデルバインディング

ルートモデルバインディング? URLパラメーター(`{id}`など)を自動でEloquentモデルに変換する機能。コントローラーで`$user`を受け取るだけでDBから取得してくれる。 を使うと、URLの {post} パラメーターを自動でEloquentモデルに変換してくれます。

通常の書き方(IDで自分で取得):

// 📁 app/Http/Controllers/PostController.php

public function show($id)
{
    $post = Post::findOrFail($id); // ← 自分でDBから取得する必要がある
    return view('posts.show', compact('post'));
}

ルートモデルバインディングを使った書き方:

// 📁 app/Http/Controllers/PostController.php

use App\Models\Post;

public function show(Post $post) // ← 型宣言するだけで自動取得!
{
    return view('posts.show', compact('post'));
}

Post $post と型宣言するだけで、Laravelが {post} のIDをDBで検索し、見つかればモデルを渡してくれます。見つからなければ自動で404エラーになります。


使えるルートを絞り込む

7つ全部が必要ない場合は only または except で絞れます。

// 📁 routes/web.php

// indexとshowだけ(読み取り専用)
Route::resource('posts', PostController::class)->only(['index', 'show']);

// destroyだけ除外
Route::resource('posts', PostController::class)->except(['destroy']);

ネストしたリソース

「投稿に紐づくコメント」のように、親子関係のリソースを扱う場合はネストできます。

// 📁 routes/web.php

Route::resource('posts.comments', CommentController::class);

/posts/{post}/comments/{comment} のような URL が生成されます。

コントローラーの受け取り方:

// 📁 app/Http/Controllers/CommentController.php

public function show(Post $post, Comment $comment)
{
    // $post と $comment が自動で取得される
    return view('comments.show', compact('post', 'comment'));
}

まとめ

  • Route::resource() 1行でCRUDの7ルートを定義できる
  • php artisan make:controller PostController --resource で対応するコントローラーも生成できる
  • 型宣言 Post $post でルートモデルバインディングが有効になり、自動でDBから取得される
  • only / except で必要なルートだけに絞れる

次回はFormRequestを使ったバリデーションの書き方を学びます。