初めてのLaravel 5.6 : (32) Route Model Binding

今回は Route Model Binding 機能を使って、コントローラを修正したいと思います。Route Model Binding とは、今までモデルの id を受け取っていた箇所で、id の代わりに、id に対応するモデルのインスタンスを受け取れる便利な機能です。


ルートの確認

php artisan route:list

+--------+-----------+-------------------------+------------------+------------------------------------------------------------------------+--------------+
| Domain | Method    | URI                     | Name             | Action                                                                 | Middleware   |
|        | DELETE    | articles/{article}      | articles.destroy | App\Http\Controllers\ArticlesController@destroy                        | web,auth     |
|        | PUT|PATCH | articles/{article}      | articles.update  | App\Http\Controllers\ArticlesController@update                         | web,auth     |
|        | GET|HEAD  | articles/{article}      | articles.show    | App\Http\Controllers\ArticlesController@show                           | web          |
|        | GET|HEAD  | articles/{article}/edit | articles.edit    | App\Http\Controllers\ArticlesController@edit                           | web,auth     |
+--------+-----------+-------------------------+------------------+------------------------------------------------------------------------+--------------+

{article} パラメータを受け取っているアクションが4つあります。

  • articles.show
  • articles.edit
  • articles.update
  • articles.destroy

これらのルートのコントローラメソッドでは、id で Articleを検索する処理が実行されています。

$article = Article::findOrFail($id);
// app/Http/Controllers/ArticlesController.php

...

class ArticlesController extends Controller {

    ...

    public function show($id) {
        $article = Article::findOrFail($id);  // $id で Articleを検索

        return view('articles.show', compact('article'));
    }

    ...

    public function edit($id) {
        $article = Article::findOrFail($id);  // $id で Articleを検索

        return view('articles.edit', compact('article'));
    }

    public function update(ArticleRequest $request, $id) {
        $article = Article::findOrFail($id);  // $id で Articleを検索

        $article->update($request->validated());

        return redirect()->route('articles.show', [$article->id])
            ->with('message', '記事を更新しました。');
    }

    public function destroy($id) {
        $article = Article::findOrFail($id);  // $id で Articleを検索

        $article->delete();

        return redirect()->route('articles.index')
            ->with('message', '記事を削除しました。');
    }
}

Route Model Binding を使うと、この検索処理をコントローラで実行する必要がなくなります。


Route Model Binding

ArticlesController.php を修正します。

// app/Http/Controllers/ArticlesController.php

...

class ArticlesController extends Controller {

    ...

    public function show(Article $article) { // $id から $article へ変更
        return view('articles.show', compact('article'));
    }

    ...

    public function edit(Article $article) { // $id から $article へ変更
        return view('articles.edit', compact('article'));
    }

    public function update(ArticleRequest $request, Article $article) { // $id から $article へ変更
        $article->update($request->validated());

        return redirect()->route('articles.show', [$article->id])
            ->with('message', '記事を更新しました。');
    }

    public function destroy(Article $article) { // $id から $article へ変更
        $article->delete();

        return redirect()->route('articles.index')
            ->with('message', '記事を削除しました。');
    }
}

今まで、$id を引数に受け取っていた4つのメソッドを Article $article を受け取るように変更しました。
Article::findOrFail($id); で、$id から記事を検索していた処理は削除しました。

驚いた事に、これだけで自動的にルートの {article} 部分に指定された id に一致する Article が $article 変数に渡されてきます。この機能を Route Model Bindeing といいます。

ルートの {article} パラメータとコントローラの $article 引数は名前を合わせておく必要があります。

今までのコントローラでも十分にシンプルだと思っていましたが、更にシンプルになり、超クールです。

公式サイト
http://laravel.com/docs/5.6/routing#route-model-binding

コメントを残す