ここまでで記事(Article)に関して、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)の実装が完了しました。いわゆる CRUD と言うやつです。実は、この CRUD を実装するに当たって、Laravel の Resource Controler の流儀に基づいてルートやコントローラを定義して来ました。今回はこの Resource Controler について見ていきます。
Laravel では、標準的な CRUD は以下のパターンで実装する流儀となっています。
操作対象が記事(Article)の場合
Method | URI | Action | 操作内容 |
---|---|---|---|
GET | /articles | ArticlesController@index | 一覧表示 |
GET | /articles/create | ArticlesController@create | 新規作成 |
POST | /articles | ArticlesController@store | 新規保存 |
GET | /articles/{article} | ArticlesController@show | 表示 |
GET | /articles/{article}/edit | ArticlesController@edit | 編集 |
PUT/PATCH | /articles/{article} | ArticlesController@update | 更新 |
DELETE | /articles/{article} | ArticlesController@destroy | 削除 |
Resoruce Controllere
Laravel では Controller を作成する際に –resource オプションを指定するとデフォルトで以下のようにメソッドが作成されます。このメソッドが上記のパターンに基づいて命名されています。
例として、PostsController.php を作成してみます。
php artisan make:controller PostsController --resource
<?php // app/Http/Controllers/PostsController.php namespace App\Http\Controllers; use Illuminate\Http\Request; class PostsController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { // } }
RESTful Routes
PostsController.php に対応するルートを定義します。
// routes/web.php Route::resource('posts', 'PostsController');
Route::resource の1行だけで全てのパターンのルートを定義することができます。
しかし、この記述だけだと何が定義されているのかよく分からないので、以下のコマンドでルートを確認することが出来ます。
php artisan route:list +--------+-----------+--------------------+------------------+-------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+--------------------+------------------+-------------------------------------------------+--------------+ | | GET|HEAD | posts | posts.index | App\Http\Controllers\PostsController@index | web | | | POST | posts | posts.store | App\Http\Controllers\PostsController@store | web | | | GET|HEAD | posts/create | posts.create | App\Http\Controllers\PostsController@create | web | | | DELETE | posts/{post} | posts.destroy | App\Http\Controllers\PostsController@destroy | web | | | PUT|PATCH | posts/{post} | posts.update | App\Http\Controllers\PostsController@update | web | | | GET|HEAD | posts/{post} | posts.show | App\Http\Controllers\PostsController@show | web | | | GET|HEAD | posts/{post}/edit | posts.edit | App\Http\Controllers\PostsController@edit | web | +--------+-----------+--------------------+------------------+-------------------------------------------------+--------------+
Name 欄に Named Route が定義されているところも、ご注目ください。
また、一部のアクションのみが必要な時は以下のように Route をカスタマイズすることも出来ます。
// routes/web.php Route::resource('posts', 'PostsController')->only(['index', 'show']); Route::resource('posts', 'PostsController')->expect(['create', 'store', 'update', 'destroy']);
※ Route::resource(‘posts’, ‘PostsController’); は確認の為だけに web.php に挿入したので、ここで削除してください。
※ PostsController.php も確認の為だけに作ったので、ここで削除してください。
Articles の Route を修正
Route::resource を覚えたので Articles もこの記述に修正します。
// routes/web.php //Route::get('articles', ['as' => 'articles.index', 'uses' => 'ArticlesController@index']); //Route::get('articles/create', ['as' => 'articles.create', 'uses' => 'ArticlesController@create']); //Route::get('articles/{id}', ['as' => 'articles.show', 'uses' => 'ArticlesController@show']); //Route::post('articles', ['as' => 'articles.store', 'uses' => 'ArticlesController@store']); //Route::get('articles/{id}/edit', ['as' => 'articles.edit', 'uses' => 'ArticlesController@edit']); //Route::patch('articles/{id}', ['as' => 'articles.update', 'uses' => 'ArticlesController@update']); //Route::delete('articles/{id}', ['as' => 'articles.destroy', 'uses' => 'ArticlesController@destroy']); Route::resource('articles', 'ArticlesController');
今まで、7行にもわたって定義してきた articles のルートは実は1行で書けてしまうのでした。
一応、artisan コマンドで route:list を確認しておきます。
php artisan route:list +--------+-----------+-------------------------+------------------+-------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-------------------------+------------------+-------------------------------------------------+--------------+ | | GET|HEAD | articles | articles.index | App\Http\Controllers\ArticlesController@index | web | | | POST | articles | articles.store | App\Http\Controllers\ArticlesController@store | web | | | GET|HEAD | articles/create | articles.create | App\Http\Controllers\ArticlesController@create | web | | | GET|HEAD | articles/{article} | articles.show | App\Http\Controllers\ArticlesController@show | web | | | PUT|PATCH | articles/{article} | articles.update | App\Http\Controllers\ArticlesController@update | web | | | DELETE | articles/{article} | articles.destroy | App\Http\Controllers\ArticlesController@destroy | web | | | GET|HEAD | articles/{article}/edit | articles.edit | App\Http\Controllers\ArticlesController@edit | web | +--------+-----------+-------------------------+------------------+-------------------------------------------------+--------------+