【Laravel】FormRequestクラスを使った高度なバリデーション|複雑な依存関係の解決法

【Laravel】FormRequestクラスを使った高度なバリデーション|複雑な依存関係の解決法 Laravel

Laravelでは、フォームのバリデーションをコントローラー内で完結させることも可能ですが、規模が大きくなるとコードの可読性や再利用性が低下します。そんなときに有効なのが FormRequest クラスです。

この記事では、FormRequest クラスを使って複雑な依存関係を含むバリデーションを行う方法について、具体的なコード例とともに解説します。

FormRequest クラスとは?

FormRequestは、バリデーションルールと認可処理をコントローラーから分離するためのLaravelの仕組みです。

以下のコマンドで作成できます:

php artisan make:request RegisterUserRequest

生成されたクラスでは、authorize()rules()メソッドを定義できます。

public function rules()
{
    return [
        'name' => 'required|string|max:255',
        'email' => 'required|email|unique:users,email',
        'password' => 'required|min:8|confirmed',
    ];
}

複雑な条件分岐のあるバリデーション

例えば、以下のようなバリデーション要件があったとします。

  • 「role」が admin の場合は「admin_code」が必須
  • 「role」が user の場合は「birth_date」が必須

このような依存関係のあるバリデーションは、rules()内で条件付きに記述できます。

public function rules()
{
    $rules = [
        'role' => 'required|in:admin,user',
    ];

    if ($this->input('role') === 'admin') {
        $rules['admin_code'] = 'required|string';
    }

    if ($this->input('role') === 'user') {
        $rules['birth_date'] = 'required|date';
    }

    return $rules;
}

FormRequest は $this でリクエスト内容にアクセスできるため、こうした条件分岐が可能になります。

バリデーションロジックをメソッドに分離して再利用性を高める

複雑な依存関係が増えてきた場合、ロジックをメソッドに切り出すことでメンテナンス性が向上します。

public function rules()
{
    return array_merge([
        'role' => 'required|in:admin,user',
    ], $this->conditionalRules());
}

protected function conditionalRules()
{
    if ($this->input('role') === 'admin') {
        return ['admin_code' => 'required|string'];
    }

    if ($this->input('role') === 'user') {
        return ['birth_date' => 'required|date'];
    }

    return [];
}

ルールを段階的に組み立てることで、読みやすく保守しやすいコードになります。

メッセージのカスタマイズ

messages()メソッドを使えば、バリデーションエラーメッセージも柔軟にカスタマイズできます。

public function messages()
{
    return [
        'admin_code.required' => '管理者コードは必須です。',
        'birth_date.required' => '生年月日を入力してください。',
    ];
}

フォームごとにユーザーフレンドリーなエラーメッセージを返せるので、UI/UXの向上にもつながります。

バリデーション後の追加チェック(withValidator)

さらに高度な処理を追加したい場合は、withValidator()メソッドを使って、カスタムロジックを挿入することも可能です。

public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->input('role') === 'admin' && $this->input('admin_code') !== 'SECRET') {
            $validator->errors()->add('admin_code', '無効な管理者コードです。');
        }
    });
}

この方法を使えば、バリデーションルールに収まらないロジックも柔軟に実装可能です。

まとめ

FormRequestクラスは、バリデーションの複雑化を防ぎつつ、構造化された安全なフォーム処理を可能にする強力な手段です。

  • 条件付きルールは if 文で柔軟に構築可能
  • ロジックを分離して可読性・再利用性を確保
  • withValidator()で追加ロジックを挿入可能

Laravelで複雑なフォームバリデーションを扱う場面では、FormRequestの積極的な活用が推奨されます。