バリデーションとルール
バリデーション
リクエストデータがエンティティにコンバートされる前に、データ型や書式のルールが適用される。
<?php $article = $articles->newEntity($this->request->getData()); if ($article->errors()) { // エンティティー検証失敗。 } ?>
エンティティ構築時のバリデーションの流れ
- バリデータオブジェクトが作成される
- table および default バリデーションプロバイダーが追加される
- 命名に沿ったバリデーションメソッドが呼び出される。たとえば validationDefault 。
- Model.buildValidator イベントが発動する
- リクエストデータが検証される
- リクエストデータがそのカラム型に対応する型に変換される
- エラーがエンティティーにセットされる
- 正しいデータはエンティティーに設定されるが、 検証を通らなかったフィールドは除外される
バリデータオブジェクトの作成
デフォルトのバリデータオブジェクト
デフォルトのバリデータオブジェクトはテーブル中でvalidationDefault()で作成される。
<?php use Cake\ORM\Table; use Cake\Validation\Validator; class ArticlesTable extends Table { public function validationDefault(Validator $validator) { $validator ->requirePresence('title', 'create') ->notEmpty('title'); $validator ->allowEmpty('link') ->add('link', 'valid-url', ['rule' => 'url']); ... return $validator; } } ?>
カスタムバリデータオブジェクト
カスタムバリデータ'update'の使用例。validationUpdate()メソッドで作成する。
<?php class ArticlesTable extends Table { public function validationUpdate($validator) { $validator ->add('title', 'notEmpty', [ 'rule' => 'notEmpty', 'message' => __('タイトルを設定してください'), ]) ->add('body', 'notEmpty', [ 'rule' => 'notEmpty', 'message' => __('本文は必須です') ]); return $validator; } } ?>
エンティティ作成時のオプションで'update'を指定。これでデフォルトのバリデータではなくupdateバリデータが適用される。
<?php $article = $articles->newEntity( $this->request->getData(), ['validate' => 'update'] // バリデーションのオプション ); ?>
バリデータの組み合わせ
バリデータ作成メソッドの中で異なるバリデータを作成することで、バリデーションを組み合わせることができる。
<?php public function validationHardened(Validator $validator) { $validator = $this->validationDefault($validator); // デフォルトバリデータオブジェクトの作成 $validator->add('password', 'length', ['rule' => ['lengthBetween', 8, 100]]); return $validator; } ?>
ルール
データが保存される前に、ドメインルールまたはアプリケーションルールが適用される。
バリデーションはデータの構文や形式が正しいことを保証するのに対し、ルールはアプリケーションやネットワークの既存の状態に対してデータを比較することに焦点を当て、データの一貫性を保証する。
ルールチェッカーの作成
ルールチェッカーはテーブルクラスのbuildRules()で定義される。
<?php use Cake\ORM\RulesChecker; // テーブルクラスの中で public function buildRules(RulesChecker $rules) { // 作成および更新操作に提供されるルールを追加 $rules->add(function ($entity, $options) { // 失敗/成功を示す真偽値を返す }, 'ruleName'); // 作成のルールを追加 $rules->addCreate(function ($entity, $options) { // 失敗/成功を示す真偽値を返す }, 'ruleName'); // 更新のルールを追加 $rules->addUpdate(function ($entity, $options) { // 失敗/成功を示す真偽値を返す }, 'ruleName'); // 削除のルールを追加 $rules->addDelete(function ($entity, $options) { // 失敗/成功を示す真偽値を返す }, 'ruleName'); return $rules; } ?>
一意性ルール
isUnique(['検証するフィールド'])でデータの一意性を検証する。
<?php use Cake\ORM\Rule\IsUnique; // 一つのフィールド $rules->add($rules->isUnique(['email'])); // フィールドのリスト $rules->add($rules->isUnique( ['username', 'account_id'], )); ?>
外部キールール
existIn('検証するフィールド', '参照先テーブル')でほかのリソースと関連づいているかどうか(外部キーに参照先テーブルのキーが入っているか)を検証する。
<?php // 一つのフィールド $rules->add($rules->existsIn('article_id', 'Articles')); // 複数キー。複合主キーに役立ちます。 $rules->add($rules->existsIn(['site_id', 'article_id'], 'Articles')); ?>
アソシエーションカウントルール
一対多、多対多の関連があるとき、validCount('関連データ名', '件数', '比較演算子', 'エラーメッセージ')で関連データの件数を検証する。
<?php // ArticlesTable.php ファイルの中で // 記事にタグは5つ以内。 $rules->add($rules->validCount('tags', 5, '<=', 'タグは 5 つまで持てます')); ?>
ルールの無効化
エンティティ保存時にオプションでルールを無効化できる。
<?php $articles->save($article, ['checkRules' => false]); ?>