CakePHPで「create時は必須入力」「update時は任意入力」のvalidationをする
CakePHPでDBにデータを保存するときにはmodelの$validate変数を使ってバリデーションをすると思うのですが、
ちょっとやり方がわからなくてハマった所があったのでメモ。
前提
- 簡単に話を進めるためにtitleとstatusというカラムをもつテーブルがあったと仮定する
やりたいこと
- 始めのinsert時にはtitleに入力がないとダメ
- statusはデフォルト値1を自動入れるのでinsert時に入力がなくてもOK
- insert時もupdate時もtitleは空文字入力禁止
- update時にstatusだけ更新したい
まず、やりたいことを実現するために「タイトルが空文字ではダメ」「タイトルは必須入力」という以下のルールを書きました。
public $validate = array( 'title' => array( 'not_empty' => array( 'rule' => 'notEmpty', 'required' => true, 'last' => true, ), // その他のルール ... ), );
これを書いたことにより、insert時にtitleがないとエラーになります。
ただ、このままだと、update時にstatusだけ更新したくて
$this->MyModel->save(array('status' => 1));
みたいに書いたとしても「titleがないから保存できないよ」ってエラーが出てしまい更新できません。
そこで、「じゃあcreate時だけrequiredになってくれればいいよ」と思い、以下のように'on' => 'create'を付けました。
public $validate = array( 'title' => array( 'not_empty' => array( 'rule' => 'notEmpty', 'required' => true, 'on' => 'create', 'last' => true, ), // その他のルール ... ), );
この状態でさっきと同様にupdateしてみると「おぉ。上手くいく!」という感じで更新できました。
ただ、今度は下のようにupdate時にtitleを空文字で設定されるとそのまま更新されてしまいます。
$this->Review->save(array( 'status' => 1, 'title' => '', // タイトルが空になっちゃう!! ));
titleが空文字で保存されてしまったら元も子もなく、
「あー、findでデータを持って来てDBにあるデータと同じ値を設定しようかなぁ」
と思ったのですが、それもイマイチだなぁと思い現段階のベター解が以下になりました。
public $validate = array( 'title' => array( 'not_empty_create' => array( 'rule' => 'notEmpty', 'required' => true, 'on' => 'create', 'last' => true, ), 'not_empty_update' => array( 'rule' => 'notEmpty', 'on' => 'update', 'last' => true, ), // その他のルール ... ), );
'not_empty'というルールを'on'を使い、
- insert時の'not_empty_create'
と
- update時の'not_empty_update'
に分け、create時の時だけ'required' => trueにするという方法。
ちょっと冗長な感じですが、同じデータを更新するよりはいいかなぁと。
何か他にやりようがありそうな気もするんですけど、ググるキーワードが思いつかず断念しました。
とりあえず作業を続けます。
あと、MacBook Air 11インチ欲しい!