Form Requestを導入してバリデーションを行う。合言葉は「1つのControllerをコンパクトに!」(Laravel)
今回はLaravelに備わっているFormRequestを利用してバリデーションを行う方法とそのメリットについて解説していきます。
Controllerでバリデーションをしている方は、FormRequestの方が良い場合が多いので、ぜひこの記事を読んだ後に実践してみてください。
Controllerでバリデーションを行う方法
殆どの方がこの方法を先に知るのではないでしょうか??
公式サイトでも一番上に出てくる方法で、
Controllerでリクエストパラメータを受け取ってそのままバリデーションを行う方法です。
公式サイトの例文をそのまま引用します
/**
* 新ブログポストの保存
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// ブログポストは有効
}
Controllerでバリデーションを行う場合でも何ら問題はありません。
別にこだわりないよって方はこちらのやり方でもOKです。どうしてもと言うなら誰も止めません。
FormRequstを使用する場合
FormReuestのファイルはコマンドを使用して作成することができます
php artisan make:request StorePostRequest
すると /app/Http/Requests/StorePostRequest.php
が生成されます。
こちらのファイルを書きかえて、ここにバリデーションを定義します。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
/**
* trueの場合にバリデーションが実行される
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* バリデーションルール
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
/**
* 定義済みバリデーションルールのエラーメッセージ取得
*
* @return array
*/
public function messages()
{
return [
'title.required' => 'A title is required'
'body.required' => 'A message is required',
];
}
/**
* バリデーションエラーのカスタム属性の取得
*
* @return array
*/
public function attributes()
{
return [
'email' => 'email address',
];
}
}
ちなみにバリデーションメッセージやカスタム属性は一応入れていますが、ここで定義する必要はありません。FormRequestの内部で定義すればそのメッセージや属性が使用されますが、そうでない場合はControllerでバリデーションを行う際と全く同じ方法で可能なので、ここでは説明しません。
さて、FormRequestのファイルを作った後はControllerに反映します
/**
* 新ブログポストの保存
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(StorePostRequest $request)
{
// ブログポストは有効
}
違いが分かりましたか?
違いはここです public function store(StorePostRequest $request)
ここがRequestではなく、作成したFormRequestのクラス名になっています。
これだけで、リクエストが送られてきた際に自動でバリデーションしてくれるんです!!
Controllerがスッキリしましたよね。
FormRequestを使うべきただ一つの理由
それは、タイトルにもある通り「Controllerをコンパクトに!」です。
どれだけファイルが多くなっても良いので、1つのControllerをコンパクトにしましょう。という考え(Thin Controller)があり、私はそれに賛成しています。
では、なぜ1つのContorllerをコンパクトにした方が良いのでしょうか。
理由はこんな感じです。
- ロジックを別ファイルにすることで再利用性が高まる
- コード量が多くなると読みにくいし
- コード量が多くなると何がどこにあるか分かりにくい
1番が大きな理由かなと思います。
他のところでも同じバリデーションを使いたいとなった場合に、あなた同じコードをコピペして書くのかい?って言うことだと思います。
バリデーション一つにしても、ユーザーがDBに保存する場合と管理者が管理画面からDBに保存する場合が考えうるので、同じバリデーションを再利用する可能性は大いにあります。
このようにContorllerに直接ロジックを書くのではなく、別ファイルに切り出すように考えると良いと思います。
今回はこれにて終わります!
Discussion