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

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


ルートの復習

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

{articles}パラメータを受け取っているアクションが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($id, ArticleRequest $request) {
		$article = Article::findOrFail($id);  // $id で Articleを検索
		$article->update($request->all());
		\Session::flash('flash_message', '記事を更新しました。');

		return redirect()->route('articles.show', [$article->id]);
	}

	public function destroy($id) {
		$article = Article::findOrFail($id);  // $id で Articleを検索
		$article->delete();
		\Session::flash('flash_message', '記事を削除しました。');

		return redirect()->route('articles.index');
	}
}

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


Route Model Binding

RouteServiceProvider.php の中で、ルートとモデルの対応付け設定を行います。

// app/Providers/RouteServiceProvider.php

...

class RouteServiceProvider extends ServiceProvider {
	protected $namespace = 'App\Http\Controllers';

	public function boot(Router $router)
	{
		parent::boot($router);

		$router->model('articles', 'App\Article');  // 追加
	}
	...
}

boot() メソッドの中で、$router->mode()を実行して、パラメータに対応するモデルを対応付けます。第1引数で指定しているのはルートのURIに記述してあるパラメータになります。第2引数はモデルのネームスペースです。


Controller

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(Article $article, ArticleRequest $request) {  // $id から $article へ変更
		$article->update($request->all());
		\Session::flash('flash_message', '記事を更新しました。');

		return redirect()->route('articles.show', [$article->id]);
	}

	public function destroy(Article $article) {  // $id から $article へ変更
		$article->delete();
		\Session::flash('flash_message', '記事を削除しました。');

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

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

公式サイト
http://laravel.com/docs/5.0/routing#route-model-binding
※ 何故かv5.1のドキュメントにRoute Model Bindingがありません。v5.0の方をご覧ください。

初めてのLaravel 5.1 : (32) Route Model Binding」への1件のフィードバック

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中