capsctrldays

2008-08-18 (月) [長年日記]

[CakePHP] バリデーションとか

Railsもそうだけど、モデルに宣言的にバリデーションをつけるのはよくない。

なので、

class Hoge extends AppModel {
    function validateHoge() {
       // reset errors
       $this->validationErrors = array();
       $this->validate = array();

       $this->validate["email"]["rule1"] = array(...);
       // ...
    }
}

みたいなのを用意して、いちいち呼び出した方がいいはず。

コントローラからは、

$this->Hoge->create();
$this->Hoge->set($this->data);
$this->Hoge->validateHoge();
$errors = $this->validateErrors($this->Hoge);

みたいな。

バリデーションと同時に、いらないキーも排除しときたいので、

class AppModel extends Model {
   function exclude($attrs = array()) {
       foreach($this->data[$this->name] as $k => $v) {
           if (!in_array($k, $attrs)) {
               unset($this->data[$this->name][$k]);
           }
       }
   }
}

とか用意しといて、

class Hoge extends AppModel {
    function validateHoge() {
        $this->exclude(array("a", "b", ...));

みたいな。

[CakePHP] Model::set

普通はこういう感じで使うけど

$data["Model"] = array("in_model" => "AAA", "out_model" => "BBB");
$this->Model->set($data);

モデル名を外すとうまくセットできない

$data = array("in_model" => "AAA", "out_model" => "BBB");
$this->Model->set($data);

でも、モデルの属性だけだとセットできる

$data = array("in_model" => "AAA");
$this->Model->set($data);

うそ。別のタイミングだ。

むー。どこでおかしくなってんだろ。

どっかにキャッシュされてるっぽいなあ

こまめに削除と再起動しよう。

ってか問題なのはidがセットできちゃうところだよなあ

コントローラの $this->data は使わないようにしないと。

本日のツッコミ(全7件) [ツッコミを入れる]
1 kou (2008-08-18 (月) 19:19)

どうして宣言的につけるのがよくないのかも、PHPもよくわかないのですが、名前は悪いと思います。<br><br>HogeクラスにvalidateHogeは冗長だと思います。validateでいいと思います。<br><br>あと、validateの中に何が入るのかがvalidateの名前からは分かりません。validateされた後の結果?<br><br>あと、あと、validateHogeでバリデーション以外のこともするのは紛らわしいのではないかと思います。明示的にバリデーションを呼ぶのであれば、excludeも明示的に呼んでもよいのではないかと思います。<br><br>あと、あと、あと、validationErrorsとvalidateErrorsはtypoだと思います。というか、$this->Hoge->validateHoge();の後に$this->validateErrors($this->Hoge);でエラーがとれるAPIはちょっとびっくりすると思います。$this->Hoge->validateErrorsとか、$this->validateHoge()ならそうだろうなぁという気はします。

2 kdmsnr (2008-08-18 (月) 19:23)

1. こっちの書き方が悪いですね。validateHoge の Hoge はクラス名ではない任意の名です。<br><br>2. 期待しない値を削除するのはこいつの責務で大丈夫だと思います。<br><br>3. これはFWの仕様

3 kou (2008-08-18 (月) 21:21)

1. やっぱり名前が悪いじゃないですか。。。<br><br>2. こいつってモデルオブジェクトのことですか?モデルオブジェクトの責務でいいと思いますが、バリデーションメソッドの責務ではないと思います。(バリデーションメソッドは破壊的じゃない気がする。)<br><br>3. FWってフレームワークのことですか!ファイアーウォールしか思い浮かばなかった。。。

4 kdmsnr (2008-08-18 (月) 21:33)

2. これも名前が悪いんでしょう。

5 yyamano (2008-08-19 (火) 04:38)

> モデルに宣言的にバリデーションをつけるのはよくない<br><br>これ理由を教えてもらえませんか。僕はバリデーションのためのメタデータを宣言的に(アノテーションやアトリビュートなどで)につけるのは、良いアイデアだと思うんですけど。

6 kdmsnr (2008-08-19 (火) 07:24)

任意の値をバリデートしてビューに戻したいからです(モデルとビューが結びついているフレームワークの制約でもありますが)。DBへの保存とバリデーションしたい場面が違うというやつですね。<br><br>http://capsctrl.que.jp/kdmsnr/wiki/bliki/?ContextualValidation

7 yyamano (2008-08-20 (水) 11:02)

あー、なるほど。バリデーションのルールとバリデーションそのものが一緒になっているのが問題なんですね。