コントローラーのファイルが大きくなってきたな、と思ったら、FormRequestを使ってみようかと真剣に考え始めました。まずは、FormRequestとは何ものかの紹介からです。
FormRequestを使わないコントローラ
FormRequestを使わないコントローラというのは、例えば以下のコードに代表されます。
namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { public function __construct() { $this ->middleware( 'auth' ); //認証したユーザーのみがアクセス可能 } public function edit() { $user = auth()->user(); // 認証したユーザーの情報を取得 return view( 'user_edit' )->with(compact( 'user' )); } public function update(Request $request ) { // リクエストのバリデーション $validated = $request ->validate([ 'name' => 'required' , 'email' => 'required|email' , ]); // DBの情報を更新 auth()->user()->update( $validated ); // ホーム画面へリダイレクト return redirect()->route( 'home' ); } } |
このコントローラを使用する、routeは以下のように定義されます。
Route::get( '/' , function () { return view( 'welcome' ); }); Auth::routes(); Route::get( '/home' , 'HomeController@index' )->name( 'home' ); Route::get( '/user/edit' , 'UserController@edit' )->name( 'user.edit' ); Route::put( '/user/edit' , 'UserController@update' )->name( 'user.update' ); |
よく見て欲しいのは、UserController::update()
のメソッド。
リクエストの入力値をバリデートして、バリデーションをパスした入力値をそのまま、EloquestのUserオブジェクト(auth()->user)のupdate()に
渡して更新です。
ちなみに、このコントローラは、ログインしたユーザーが自分の情報を編集するためです。Laravelのデフォルトのプロジェクトにはユーザー認証のコードがついてきますが、この機能はありません。
FormRequestを使用したら
まず、コマンドラインから、FormRequestの作成です。
$ php artisan make :request UserRequest |
これで、UserRequest.phpが作成されます。それを以下のように編集します。
amespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class UserRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; // すでにUserController::__construct()でチェックしてあるので、true } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required' , 'email' => 'required|email' , ]; } } |
見ての通り、コントローラにあったバリデーションルールが移動されています。
コントローラの方は、
namespace App\Http\Controllers; use App\Http\Requests\UserRequest; //ここで宣言 class UserController extends Controller { public function __construct() { $this ->middleware( 'auth' ); } public function edit() { $user = auth()->user(); return view( 'user_edit' )->with(compact( 'user' )); } public function update(UserRequest $request ) { auth()->user()->update( $request ->validated()); // 1行になりました return redirect()->route( 'home' ); } } |
FormRequestを使うことでコントローラのコードの行数は減りました。しかし、FormRequestの定義のファイルが増えて全体のコードの行数は増えたことも事実。今回のような、簡単なコードではあまり得したことにはならない感じですね。ない方がわかりやすいとも思えます。しかし、もしバリデーションルールがもっとたくさんあったら、FormRequestはベターなのは明らかです。コードが複雑になったらリファクターして新規の関数を作成するのと同じかな。
しかし、FormRequestを使うことに関して他の利点はなんでしょう?次回からそれらの利点を探ってみます。
編集のブレード
参考として、作成したブレードファイルも掲載します。resources/views/auth/register.blade.phpをもとにしましたが、Eメールの入力において、type="email"
のところ、type="text"
にしています。バリデーションエラーの表示をテストしたかったためです。
@ extends ( 'layouts.app' ) @section( 'content' ) <div class = "container" > <div class = "row justify-content-center" > <div class = "col-md-8" > <div class = "card" > <div class = "card-header" >{{ __( 'Register' ) }}</div> <div class = "card-body" > <form method= "POST" action= "{{ route('user.edit') }}" > @csrf @method( 'PUT' ) <div class = "form-group row" > <label for = "name" class = "col-md-4 col-form-label text-md-right" >{{ __( 'Name' ) }}</label> <div class = "col-md-6" > <input id= "name" type= "text" class = "form-control @error('name') is-invalid @enderror" name= "name" value= "{{ old('name', $user->name) }}" required autocomplete= "name" autofocus> @error( 'name' ) <span class = "invalid-feedback" role= "alert" > <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class = "form-group row" > <label for = "email" class = "col-md-4 col-form-label text-md-right" >{{ __( 'E-Mail Address' ) }}</label> <div class = "col-md-6" > <input id= "email" type= "text" class = "form-control @error('email') is-invalid @enderror" name= "email" value= "{{ old('email', $user->email) }}" required autocomplete= "email" > @error( 'email' ) <span class = "invalid-feedback" role= "alert" > <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class = "form-group row mb-0" > <div class = "col-md-6 offset-md-4" > <button type= "submit" class = "btn btn-primary" > {{ __( 'Register' ) }} </button> </div> </div> </form> </div> </div> </div> </div> </div> @endsection |