LaravelのFormRequestでバリデーションする!

Laravel Laravel

フォームから飛んできた値をバリデーションするときに、Requestのままバリデーションすることもあると思います。
FormRequest(フォームリクエスト)にしておくと、ファイルも分割できるし見やすいのでオススメです。

FormRequest(フォームリクエスト)でのバリデーションについて、使い方を書いて行きます。

Requestでバリデーションすると?

ControllerでRequestを使ってバリデーションした場合は下記のようになるかと思います。
よくあると思いますが、保存処理の箇所でバリデーションをかけています。

    public function save(Request $request)
    {
        $request->validate(
            [
                'board_title' => 'required|max:30',
                'user_name' => 'required|max:30',
                'about_text' => 'required',
                'password' => 'required'
            ]
        );

     // --- 保存処理:省略 ---
        return redirect()->route("top.index");
    }

FormRequest(フォームリクエスト)でバリデーションする

実際にFormRequest(フォームリクエスト)を作って、解説と動作の確認をしています。
作ってみたFormRequest(フォームリクエスト)は掲示板に投稿する時に使用するものです。

FormRequestを作る

FormRequestを作ってバリデーションすると、ソースがスッキリします。
リクエストを受けた瞬間にバリデーションをしてくれるのでいい感じです。

FormRequestを作るときは下記のコマンドで作成します。

php artisan make:request [作成クラス名]

作ったら下記のようになります。今回はBoardCreateRequestというクラス名で作りました。
appHttpRequests 配下に入ります。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class BoardCreateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

authorizeメソッドは認証をチェックする箇所らしいので、特にやることがない場合はtrueを返しておいてOKです
falseを返したままにしておくと、FormRequestを使ったときにエラーになります。
下記のように修正してみました。

class BoardCreateRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    /**
     * バリデーションルール
     * @return array
     */
    public function rules()
    {
        return [
            'board_title' => 'required|max:30',
            'user_name' => 'required|max:30',
            'about_text' => 'required',
            'password' => 'required'
        ];
    }
}

FormRequestを使う

最初にRequestでやっていたバリデーションをFormRequestにします。

    public function save(BoardCreateRequest $request)
    {
     // --- 保存処理:省略 ---
        return redirect()->route("top.index");
    }

validateの中がなくなって、スッキリしました。
この状態で、エラーになると下記のように英語で表示されます。

バリデーションメッセージの日本語化

resources\lang\en\validation.phpのファイルを日本語化してメッセージを変えるのが基本かと思います。
(enではなくjaのディレクトリを作って、そこにコピーすると、なお良いですね。)

ここではFormRequestにまとめて、メッセージ定義する方法を紹介しています。(共通のメッセージを使わない場合はこっちかと思います)
今回はメッセージは直に書いていますが、下記にあるLangクラスを使うようにすると、別ファイルに定義できるのでいいですよ。

項目名(attributes)の定義

項目名を定義してあげます。attributesをオーバーライドして定義します。

    /**
     *  バリデーション項目名定義
     * @return array
     */
    public function attributes()
    {
        return [
            'board_title' => 'タイトル',
            'user_name' => '名前',
            'about_text' => '説明文',
            'password' => 'パスワード'
        ];
    }

配列のキーで項目名、値にメッセージ表示に使いたい名前を定義します。

通常は項目名でいいかと思います。
上記はメッセージを出すときに使います。

メッセージ(messages)の定義

表示するメッセージを定義します。

    /**
     * バリデーションメッセージ
     * @return array
     */
    public function messages()
    {
        return [
            'board_title.required' => ':attributeを入力してください。',
            'board_title.max' => ':attributeは30文字以下で入力してください。',
            'user_name.required' => ':attributeを入力してください。',
            'user_name.max' => ':attributeは30文字以下で入力してください。',
            'about_text.required' => ':attributeを入力してください。',
            'password.required' => ':attributeを入力してください。'
        ];
    }

これでメッセージが表示できます。:attributeで項目名を定義します。
配列のキーで項目名.バリデーション 値で、メッセージを定義します。

日本語化したFormRequest全文

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\HttpFormRequest;

class BoardCreateRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    /**
     * バリデーションルール
     * @return array
     */
    public function rules()
    {
        return [
            'board_title' => 'required|max:30',
            'user_name' => 'required|max:30',
            'about_text' => 'required',
            'password' => 'required'
        ];
    }

    /**
     *  バリデーション項目名定義
     * @return array
     */
    public function attributes()
    {
        return [
            'board_title' => 'タイトル',
            'user_name' => '名前',
            'about_text' => '説明文',
            'password' => 'パスワード'
        ];
    }

    /**
     * バリデーションメッセージ
     * @return array
     */
    public function messages()
    {
        return [
            'board_title.required' => ':attributeを入力してください。',
            'board_title.max' => ':attributeは30文字以下で入力してください。',
            'user_name.required' => ':attributeを入力してください。',
            'user_name.max' => ':attributeは30文字以下で入力してください。',
            'about_text.required' => ':attributeを入力してください。',
            'password.required' => ':attributeを入力してください。'
        ];
    }
}

エラーが表示されない?(bladeファイルにエラー表示の追加)

bladeに受け取ったエラーを表示するエリアを設けないと表示されないため、下記のように表示したい場所にタグを追加します。

@if ($errors->any())
    <div class="alert alert-danger mt-3">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

バリデーションでエラーになると、Laravelでは$errorsの変数に配列形式でエラーの内容を保持しています。
$errors->any()でエラーがある場合は、@foreachで配列を全て回してエラー内容を出力するようにしています。

動作確認&まとめ

こんな感じで、メッセージが表示されます。
別ファイルにしておくことでControllerの中身がスッキリして処理が見やすくになるのでお勧めです。

また、同じリクエストを受けるときには同じFormRequestを引数に書いておけばいいので、楽になります。
積極的に使っていきましょう。

コメント

タイトルとURLをコピーしました