N_OR’s diary

無職が何か言ってる

laravelでのvalidation処理3

laravelで色んなvalidationを試す。 リクエストクラスを自作してvalidationを設定する方法。

これまでの処理1処理2に比べると一番現実的な気がする。

今後、絶対にlaravelで用意されている方法以外のエラーチェック(ruleの自作)が必要になるので、Validationとして独立して記述されていた方が拡張する際にもごちゃごちゃしなくなると思うし。

リクエストクラスの作成

php artisan make:request ファイル名

作成したファイルを以下になるように修正・メソッド追加。

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;

class ファイル名 extends FormRequest
{
    /** true:エラーあり */
    private $has_error;
    public function getHasError(): bool
    {
        return $this->has_error;
    }

    public function authorize()
    {
        // サンプルのため承認はすべてOK
        return true;
    }

    public function rules()
    {
        return
            // チェック内容
            [
                'id' => 'required',
                'name' => 'required',
                'email' => 'required',
            ];
    }

    public function messages()
    {
        return
            // エラー文言
            [
                'id.required' => ':attributeは必須です。',
                'name.required' => ':attributeは必須です。',
                'email.required' => ':attributeは必須です。',
            ];
    }

    public function attributes()
    {
        return
            // attribute
            [
                'id' => 'ID',
                'name' => '名前',
                'email' => 'email'
            ];
    }

    protected function failedValidation(Validator $validator)
    {
        // エラーの発生を検知
        $this->has_error = true;

        // Validationでエラー検知時の処理。
        // requestで設定されたチェックはControllerに到達する前にValidationエラー判定される
        //(詳しいタイミングは追ってない)
        // ここでexceptionが発生したらリダイレクトされる動作になる。
        // 今回、エラー時の動作はコントローラ側に任せたいのでValidationは発生させない。
    }

    public function getValidatedMessage()
    {
        // エラー時にメッセージを取り出すため
        return $this->validator->messages();
    }
}

この例ではgetHasErrorとgetValidatedMessageは筆者の感性で作ったメソッド。あとはオーバーライド。

コントローラ側で自作リクエストを利用する。

コントローラで以下の様に修正。 もともとRequest型だったものを自作のリクエストに置き換えれば良い。

testMethod到達時にはエラーチェックが完了しているため、エラーチェックの結果を取り出してエラーがあれば相応の処理をする。

use App\Http\Requests\自作したリクエスト

// 引数のRequest型を作成したカスタマイズしたRequestに置き換える
public function testMethod(自作リクエストクラス $request)
{
    // エラーチェック
    if ($request->getHasError()) 
    {
        $res = new class
        {
            public $has_error = true;
            public $message = null;
        };

        $res->message = $request->getValidatedMessage();

        Log::debug('エラーあり' . json_encode($res));
        
        return json_encode($res);
    }
    ・・・略
}