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 は使わないようにしないと。

どうして宣言的につけるのがよくないのかも、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()ならそうだろうなぁという気はします。
1. こっちの書き方が悪いですね。validateHoge の Hoge はクラス名ではない任意の名です。<br><br>2. 期待しない値を削除するのはこいつの責務で大丈夫だと思います。<br><br>3. これはFWの仕様
1. やっぱり名前が悪いじゃないですか。。。<br><br>2. こいつってモデルオブジェクトのことですか?モデルオブジェクトの責務でいいと思いますが、バリデーションメソッドの責務ではないと思います。(バリデーションメソッドは破壊的じゃない気がする。)<br><br>3. FWってフレームワークのことですか!ファイアーウォールしか思い浮かばなかった。。。
2. これも名前が悪いんでしょう。
> モデルに宣言的にバリデーションをつけるのはよくない<br><br>これ理由を教えてもらえませんか。僕はバリデーションのためのメタデータを宣言的に(アノテーションやアトリビュートなどで)につけるのは、良いアイデアだと思うんですけど。
任意の値をバリデートしてビューに戻したいからです(モデルとビューが結びついているフレームワークの制約でもありますが)。DBへの保存とバリデーションしたい場面が違うというやつですね。<br><br>http://capsctrl.que.jp/kdmsnr/wiki/bliki/?ContextualValidation
あー、なるほど。バリデーションのルールとバリデーションそのものが一緒になっているのが問題なんですね。