CakePHP3のバリデーションは2度動く!
CakePHP2の時は save
でバリデーションが実行されてましたね。
もちろんCakePHP3でも save
でバリデーションが実行されますが、
2種類のバリデーション実行タイミングがあります。
どこで実行されるの?
1個目が以下のように newEntity
と patchEntity
にPOST値等のデータを与えて Entity
を作ったタイミングでバリデーションが実行されます。
$entity = $table->newEntity($data);
$patchEntity = $table->patchEntity($entity, $data);
注意するポイントとしては、バリデーションに引っかかった項目は 戻り値の Entityに反映されません
バリデーションの記述場所
// src/Model/Table/HogeTable.php
// ここにEntity作成時のバリデーションを記述します。
public function validationDefault(Validator $validator)
{
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create');
$validator
->allowEmpty('title');
}
バリデーションに引っかかったかのチェック
以下のように Entityのerrors
メソッドを実行することでエラーの一覧を取得できます
※手動で実行しなくても、save
実行時に自動的に実行されます。
$entity = $table->newEntity($data);
$entity->errors();
or
$table->save($entity); // <-- return false
save時のバリデーションはどこに記述すればいいの?
以下のように buildRules
にsave時のバリデーションを記述します。
// src/Model/Table/HogeTable.php
public function buildRules(RulesChecker $rules)
{
// タイトルにテストという文字を許可しない
$rules->add(function ($entity, $options) {
if ($entity->title != 'テスト') {
return true;
} else {
return false;
}
}, 'test', [
'errorField' => 'title',
'message' => '「テスト」は登録することが出来ません'
]);
// HogeTableクラス内のcheckStatusメソッドを実行
$rules->add([$this, 'checkStatus'], 'status', [
'errorField' => 'status',
'message' => 'ステータスが有効ではありません'
]);
}
バリデーションに引っかかったかのチェック
バリデーションに引っかかった場合は、save
メソッドがfalseを返します。
バリデーションエラーの中身を確認したい場合は、 Entity作成時と同じ Entityのerrors
を使用します。
まとめ
- POST入力値等の入力値チェックは
validationDefault
に記述する - saveの入力値チェック(Entityチェック)は
buildRules
に記述する
CSVアップロードからのデータ登録のような状況であれば -
validationDefault
でCSVファイルのフォーマットチェック -
buildRules
でCSVから読み込ん文字列のバリデーション
というように明示的にバリデーションを切り分けることが出来るのでうまく使えば可読性を高めることが可能になります!