CakePHP3で入力された複数のカラム同士を比較するバリデーションを作ってみた。
今回のネタは合っているのかどうかよくわかっていません。
やりたかったことは大したことではなく
- 入力されたFrom日付とTo日付の比較
です。
よくあるアレです。入力されたFrom日付がTo日付より未来日の場合はダメというやつです。
最初はvalidationDefaultをごにょごにょやっていたのですが、どうも上手くできず。
もしかしたらできないのかもしれませんが、その辺調べていません。
ですので、buildRulesの方に実装してみました。
以前書いたように、CakePHP3のバリデーションには2種類あります。
ひとつはPOSTデータを送信する際に処理される「validationDefault」、もうひとつはsaveメソッド実行時に処理される「buildRules」です。
ごにょごにょと触った感じ、validationDefaultの方はPOSTデータのカラムをひとつずつ、何らかのバリデーションを実行しているように思えました。
CakePHP2の頃は入力カラム同士でバリデーションできたような気がするのですが、気のせいだったかもしれません。
前置きはともかく、こんな処理を作って実装しました。
昔の自分が書いたコードを雑に修正しただけなんですが。
<?php public function buildRules(RulesChecker $rules) { // 開始日時と終了日時の入力範囲チェック $rules->add( function ($entity, $options) { if ($entity->to_time < $entity->from_time) { return false; } else { // 未入力の場合はtrueで返す return true; } }, [ 'errorField' => 'start_datetime', 'message' => '開始日時に設定された日付が、終了日時より未来日として設定されています。' ] ); // 処理結果を返す return $rules; }
この処理はTableに書いてあるのですが、$entityというのはEntity配下に作成するであろう対象テーブルのエンティティです。
エンティティから比較したいカラムを抜いてきて、それを単純に比較しているだけです。
あとはCakePHP3のバリデーションルールに沿って、明示的にtrue / falseを返す。これだけです。
今回は日付のバリデーションなので、Controller側に直接書いたり入力時点でJavaScriptで判定したりとかでもいいと思います。
なんですが、バリデーションはバリデーションとしてまとまってた方がいいかなと。
これもまた個人的な好みです。