😎

Form Requestを導入してバリデーションを行う。合言葉は「1つのControllerをコンパクトに!」(Laravel)

2021/03/15に公開

今回は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. ロジックを別ファイルにすることで再利用性が高まる
  2. コード量が多くなると読みにくいし
  3. コード量が多くなると何がどこにあるか分かりにくい

1番が大きな理由かなと思います。

他のところでも同じバリデーションを使いたいとなった場合に、あなた同じコードをコピペして書くのかい?って言うことだと思います。

バリデーション一つにしても、ユーザーがDBに保存する場合と管理者が管理画面からDBに保存する場合が考えうるので、同じバリデーションを再利用する可能性は大いにあります。

このようにContorllerに直接ロジックを書くのではなく、別ファイルに切り出すように考えると良いと思います。

今回はこれにて終わります!

Discussion