コントローラーのファイルが大きくなってきたな、と思ったら、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メルマガ購読の申し込みはこちらから。