(7)
(0)
(1)
(0)
Total: 8 CakePHP Behaviorでバリデーション周りの効率化を図る 応用編
前回紹介したBasicValidationBehaviorを使って、動的にバリデーションを切り替える方法を紹介します。
共通のモデルを複数のフォームで利用している場合にバリデーションの定義を動的に変更したい場合などに有効です。
例1:新規登録時と編集時でバリデーションの登録項目を変更する
対応1)loadValidate()メソッドに引数を追加し、条件によって分岐させる
[モデル内の処理]
-
function loadValidate($action = 'add') {
-
'name' => 'required | maxLen[50]',
-
'email' => 'required | email | isUnique | maxLen[200]',
-
'password' => 'required | single | maxLen[20] | minLen[6]',
-
're_password' => 'required | confirm[password]',
-
'sex' => 'required | numeric | maxLen[1]',
-
'birthday' => 'required | ymd',
-
'tel' => 'required | phone | maxLen[13]',
-
'zip' => 'required | zip | maxLen[8]',
-
'pref' => 'required | maxLen[12]',
-
'addr1' => 'required | maxLen[200]',
-
'addr2' => 'maxLen[200]',
-
);
-
// 新規登録時以外はパスワード関連の項目を無効にする
-
if($action !== 'add'){
-
}
-
$this->setValidate($valid);
-
}
対応2)コントローラーでモデルのvalidate()やsave()前にloadValidate()を明示的に実行する
[コントローラー内の処理]
-
function add(){
-
// 処理を省略
-
-
$this->TestUser->set($this->data);
-
// バリデーションを設定
-
$this->TestUser->loadValidate('add');
-
if($this->TestUser->validates()) {
-
-
// 処理を省略
-
}
-
-
function edit($id = null){
-
// 処理を省略
-
-
$this->TestUser->id = $id;
-
$this->TestUser->set($this->data);
-
// バリデーションを設定
-
$this->TestUser->loadValidate('edit');
-
if($this->TestUser->validates()) {
-
-
// 処理を省略
-
}
例2:入力された条件でバリデーションを変更したい
例として、性別が女性(sex==2)だったら電話番号(tel)を必須にする場合
対応)loadValidate()メソッド内で$this->data(モデルのデータ)により分岐させる
[モデル内の処理]
-
function loadValidate() {
-
'name' => 'required | maxLen[50]',
-
'email' => 'required | email | isUnique | maxLen[200]',
-
'password' => 'required | single | maxLen[20] | minLen[6]',
-
're_password' => 'required | confirm[password]',
-
'sex' => 'required | numeric | maxLen[1]',
-
'birthday' => 'required | ymd',
-
'zip' => 'required | zip | maxLen[8]',
-
'pref' => 'required | maxLen[12]',
-
'addr1' => 'required | maxLen[200]',
-
'addr2' => 'maxLen[200]',
-
);
-
// 性別が女性(sex==2)だったら電話番号(tel)を必須
-
$valid['tel'] = 'required | phone | maxLen[13]';
-
}else{
-
$valid['tel'] = 'phone | maxLen[13]';
-
}
-
$this->setValidate($valid);
-
}
※上記の例ではmodel->set()によりデータが設定された後にmodel->validate()が実行されることを想定しています。
※明示的に行う場合は、以下のようにmodel->set()後にmodel->loadValidate()を明示的に実行します。
[コントローラー内の処理]
-
function edit($id = null){
-
// 処理を省略
-
-
$this->TestUser->id = $id;
-
$this->TestUser->set($this->data);
-
// データセット後にバリデーションを変更する
-
$this->TestUser->loadValidate();
-
// 以下はいつもの処理
-
if($this->TestUser->validates()) {
-
$M->save();
-
$this->Session->setFlash('情報を保存しました。');
-
return;
-
} else {
-
$this->Session->setFlash('入力に誤りがあります。内容を確認してください。');
-
}
-
$this->data = am($this->data, $this->TestUser->data);
-
-
// 処理を省略
-
}
例3:POSTされたデータのみチェックしたい
管理画面などで一部の項目だけを更新するフォームが数パターンあることを想定。
例1のような分岐処理でも対応できますが、ビヘイビアのintersectValidate()メソッドを利用するほうが簡単です。
対応)コントローラーでモデルのvalidate()やsave()前にintersectValidate()を実行する
[コントローラー内の処理]
-
function edit($id = null){
-
// 処理を省略
-
-
$this->TestUser->id = $id;
-
$this->TestUser->set($this->data);
-
// POST されたものだけをチェックする
-
$this->TestUser->intersectValidate($this->data);
-
// 以下はいつもの処理
-
if($this->TestUser->validates()) {
-
$M->save();
-
$this->Session->setFlash('情報を保存しました。');
-
return;
-
} else {
-
$this->Session->setFlash('入力に誤りがあります。内容を確認してください。');
-
}
-
$this->data = am($this->data, $this->TestUser->data);
-
-
// 処理を省略
-
}
例4:特定の項目のみチェックしたい
対応)例2のようにintersectValidate()メソッドを使い、引数に項目名配列を渡します
[コントローラー内の処理]
-
function edit($id = null){
-
// 処理を省略
-
-
$this->TestUser->id = $id;
-
$this->TestUser->set($this->data);
-
// 特定の項目だけをチェックする
-
// 以下はいつもの処理
-
if($this->TestUser->validates()) {
-
$M->save();
-
$this->Session->setFlash('情報を保存しました。');
-
return;
-
} else {
-
$this->Session->setFlash('入力に誤りがあります。内容を確認してください。');
-
}
-
$this->data = am($this->data, $this->TestUser->data);
-
-
// 処理を省略
-
}
関連するその他の記事
Comments
Leave a Reply