write ahead log

ロールフォワード用

Laravelで複数フィールドを組み合わせてバリデーションした時のメモ

FormRequestを使ってバリデーションを書いていた時に, ややこしい条件でバリデーションをかけたくなった.

個別のフィールドに対して検証するのではなく, フィールド2つ以上を組み合わせて検証とか, DBの値を使ってとか.

単一のフィールドそれぞれの検証なら, よくあるサンプルだと以下のように書く.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class HogeRequest extends FormRequest
{
    [...]

    /**
    * 検証ルール定義
    * (field1と2は必須)
    */
    public function rules()
    {
        return [
            'field1'   => ['required'],
            'field2'   => ['required'],
        ];
    }

    [...]
}

しかしまぁ, 現実は込み入っているので,

  • field1が1~10なら
  • field2は20~30のみ入力可能

とかややこしい分岐が入ったりする.
(これは思い付きのかなり適当な例だけど)

そんな時には自分でメソッドを定義して検証できる.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class HogeRequest extends FormRequest
{
    [...]

    /**
    * 検証ルール定義
    * (field1と2は必須)
    */
    public function rules()
    {
        /**
        * 検証用の関数
        *   $attribute: 検証中の属性名
        *   $value    : 検証中の属性の値
        *   $fail     : 失敗時に呼び出すメソッド?
        **/ 
        $validate_func = function($attribute, $value, $fail) {
            // 入力の取得
            $input_data = $this->all();

            // 条件に合致しなかったら失敗にする
            if (1 <= $input_data['field1'] && $input_data['field1'] <= 10) {
                if ($input_data['field2'] < 20 || 30 < $input_data['field2']) {
                    $fail('範囲外です.'); // エラーメッセージ
                }
            }
        };

        // ルール定義
        return [
            'field1'   => ['required'],
            'field2'   => ['required', $validate_func],  // 上記のルールを使う
        ];
    }

    [...]
}
もう少し調べてみると

なんかruleの追加やバリデーション定義も割と簡単にできそう.

laravel5.6, 5.7 独自のバリデーションルールを追加しよう! - のるぼるのるの

あと, ある程度の複雑さならsometimes使えば対処できそう.
(そもそもたくさんルールがあるので)

Laravel5.5 - バリデーション

修業が足りない.