カスタムバリデーションルールとは
Laravelには豊富な組み込みバリデーションルールが用意されていますが、アプリケーション固有の検証ロジックが必要な場面もあります。カスタムバリデーションルールを使うと、再利用可能な検証ロジックをクラスやクロージャとして定義し、標準のルールと同じように使えます。 カスタムルールを定義する方法は主に2つあります。- ルールオブジェクト — 再利用性が高く、テストしやすい
- クロージャ — 一度だけ使うシンプルなルールに向いている
ルールオブジェクト
ルールクラスを生成する
make:rule Artisanコマンドで新しいルールクラスを生成します。生成されたクラスは app/Rules ディレクトリに配置されます。
ValidationRuleインターフェースを実装する
生成されたクラスにvalidate メソッドを実装します。このメソッドはバリデーション失敗時に $fail クロージャを呼び出します。
$fail クロージャに渡す文字列には :attribute プレースホルダーを使えます。Laravelがフィールド名に置き換えます。
ルールオブジェクトを適用する
ルールオブジェクトのインスタンスをバリデーション配列に渡します。rules() メソッドでも同様に使えます。
翻訳キーを使ったエラーメッセージ
エラーメッセージをハードコードする代わりに、翻訳キーを使うこともできます。lang/ja/validation.php にメッセージを追加します。
複数のエラーメッセージを追加する
一つのフィールドに複数のエラーを報告するには、$fail を複数回呼び出します。
クロージャベースのルール
アプリケーション内で一度だけ使うシンプルなルールは、クラスを作らずクロージャで定義できます。Implicitルール(値が空でも実行する)
デフォルトでは、フィールドが空または存在しない場合、カスタムルールは実行されません。空の値に対してもルールを実行したい場合は、--implicit オプションを付けてクラスを生成します。
ImplicitRule インターフェースを実装しています。このインターフェース自体は追加のメソッドを持たず、Laravelへのシグナルとして機能します。
データアクセス
DataAwareRule — フォーム全体のデータにアクセスする
他のフィールドの値に基づいてバリデーションしたい場合は、DataAwareRule インターフェースを実装します。setData メソッドがバリデーション開始前に自動で呼び出されます。
ValidatorAwareRule — バリデーターインスタンスにアクセスする
バリデーターが持つすべての情報(失敗したルール、カスタムメッセージなど)にアクセスするには、ValidatorAwareRule インターフェースを実装します。
実践的なユースケース
日本語文字チェック
全角・半角の文字種を検証するルールです。電話番号フォーマット検証
日本の電話番号形式を検証するルールです。テナントIDつきのユニーク制約
マルチテナントアプリケーションでよくある、テナントスコープ内でのユニーク制約です。1
ルールクラスを作成する
2
フォームリクエストで使用する
3
更新時はIDを除外する
既存レコードを更新する場合は、自分自身のIDを除外して重複チェックします。
サービスプロバイダーでのルール登録
Validator::extend() でルールを追加する
Validator::extend() を使うと、文字列形式('rule_name')でカスタムルールを使えるようになります。AppServiceProvider の boot() メソッドで登録します。
Validator::extend() で登録したルールは文字列として指定できます。
Rule クラスにスタティックメソッドとして追加する
Rule ファサードにマクロを追加することで、Rule::myRule() のような流暢なAPI(Fluent API)を提供できます。
内部実装の詳細
Illuminate\Validation\Validator がカスタムルールを呼び出す仕組みを見てみましょう。
バリデーター内では validateAttribute() が各フィールドを処理します。ルールが ValidationRule インターフェースを実装している場合、validateUsingCustomRule() メソッドが呼び出されます。
ImplicitRule の処理は isImplicit() メソッドで判断され、値が空の場合でもルールのチェックを実行します。
関連ページ
バリデーション(入門)
コントローラーやフォームリクエストでの標準的なバリデーション方法を確認します。