カスタムバリデーションルール
- モデル名:Employee
- コントローラ名:Validations(紛らわしいなあ、と後で思う)
- 上記で使用するモデルを$usesでEmployeeに設定
モデル
APP/model/employee.php
- カスタムバリデーションルール:$validate_edit
- 一つのフィールドに対し複数のルールを設定
- 最初にエラーになったルールでバリデーションを停止するため"last"=>true設定
- カスタムバリデーションメソッドcheckNameを定義。複雑なバリデーションに対応。
<?php class Employee extends AppModel{ var $name = 'Employee'; var $recursive = 3; //関連するレコードも最大限取得 var $validate = array( /* 複数のカスタムバリデーションルールを設定しないときはここに書く */ ); //バリデーションルール:編集、追加 var $validate_edit = array( 'name' => array( array("rule"=>VALID_NOT_EMPTY, "message"=>"名前が空白です", "last"=>true,), array("rule"=>array("checkName"), "message"=>"登録済みです", "last"=>true, "on"=>array("create")), ), 'past_score' => array( array("rule"=>VALID_NOT_EMPTY, "message"=>"過去の得点が空白です", "last"=>true,), array("rule"=>VALID_NUMBER, "message"=>"数値を入力してください", "last"=>true,), ), ); function checkName(){ if(!$this->isUnique($this->data["Employee"]["name"])){ return false; } return true; } } ?>
APP/app_model.php
- beforeValidate:validate関数がコールされると自動的に呼ばれるコールバック関数
- 冒頭でオリジナルのバリデーションルールを保存する。
- validate実行前に呼び出し元で、validationSetにカスタムバリデーション名をセットする。カスタムバリデーションルールセットはモデルで定義。モデルでvalidate_editで定義したなら「edit」を設定(コントローラ参照)。
- afterValidate:カスタムバリデーションルールの後始末関数(独自)
- 保存しておいたオリジナルのバリデーションルールを再設定。
- validate:親クラスのvalidate関数をオーバーライドしたもの。
- 冒頭で親クラスのvalidate関数を呼ぶ
- 最後にafterValidateを呼んで後始末
<?php class AppModel extends Model{ //コールバック関数 function beforeValidate(){ debug("AppModel::beforeValidate called"); //for Debug $this->validateOrg = $this->validate; //オリジナルのバリデーションルールの保存 if ($this->validationSet){ $param = 'validate_' . $this->validationSet; //カスタムruleの決定 $this->validate = $this->{$param}; //カスタムruleの読み込み } return true; } //非コールバック関数 function afterValidate(){ debug("AppModel::afterValidate called"); //for Debug $this->validate = $this->validateOrg; //オリジナルのバリデーションルールの再設定 return true; } //バリデーション function validates(){ debug("AppModel::validates called"); //for Debug $errors = parent::validates(); //親クラスのvalidate関数を呼ぶ(フラグをセット) //後始末 $this->afterValidate(); //AppModel::afterValidate return $errors; } }
コントローラ
APP/controllers/validations_controller.php
- バリデーション実行後はモデルのデータを呼び出すような関数を実行しない(read等)。エラーフラグがリセットされる(これで二日悩む)。
<?php class ValidationsController extends AppController { var $name = 'Validations'; var $uses = array('Employee'); //index function index($id=null){ $this->pageTitle = "データバリデーションの例"; $this->Employee->id = $id; debug("ValidationsController::index called"); //for Debug if($this->data){ //フォームよりデータを受信 $this->Employee->validationSet = 'edit'; //カスタムルールセット名を設定 $rtn = $this->Employee->set(array("Employee"=>$this->data["Validation"])); //データをセット //save():引数無しだと自動的にデータバリデーションが実行される if($this->Employee->save()){ //データ保存時にvalidates実行:OK $this->flash('編集されたデータを保存しました', '/menu'); } //NG:もとの画面 $this->set('employee', array("Employee"=>$this->data["Validation"])); }else{ //初期表示 //validationした後にEmployeeモデルのデータを取得するとEmployeeモデルのvalidation flagがクリアされてしまうので注意 $this->set('employee', $this->Employee->read()); } } //index } //ValidationsController ?>
ビュー
APP/views/validations/index.ctp
-
- Form::error(モデル名.フィールド名)であら便利。
<?php echo $form->create('Validation', array('method'=>'post', 'action'=>"/index/{$employee['Employee']['id']}/")); ?> <table> <tr><th>氏名</th><td> <?php echo $form->text('name', array('value'=>$employee['Employee']['name'])); echo $form->error('Employee.name'); ?> </td></tr> <tr><th>過去の持点</th><td> <?php echo $form->text('past_score', array('value'=>$employee['Employee']['past_score'])); echo $form->error('Employee.past_score'); ?> </td></tr> </table> <?php echo $form->hidden('id', array("value"=>$employee['Employee']['id'])); ?> <?php echo $form->end('変更'); ?>
エラーフラグがリセットされる原因に気づかなくて大変疲れました・・・。