開発メモや日ごろ思ったことなどを書きためるサイトです。サイト管理者は、SE、Web開発者。最近はiPhone、Android開発に興味が出てきてすこしずつ勉強中。
CakePHPの動作が難解なのでめも。
1.同一モデルの複数レコードの保存
※insertしたいのでidは指定しない
$data = array(
'Article' => array(
'0' => array(
'name' => 'a',
'price' => 1000),
'1' => array(
'name' => 'b',
'price' => 5000)));
$this->Article->saveAll($data);
2.単一レコードに結びつく複数モデルの保存
Categoryに結びつくArticleを作成
$data = array(
'Category' => array(
'id' => 1),
'Article' => array(
'0' => array(
'name' => 'a',
'price' => 1000),
'1' => array(
'name' => 'b',
'price' => 5000)));
$this->Article->saveAll($data);
ここで一つ問題が発生
Articleモデルのarticle.phpのvalidateに下記のような記述をした。
$validate = array(
'category_id' => array(
'notempty' => array(
'rule' => array('notempty')
),
),
saveAllは第二引数のオプションに何もしないと、一度すべてのデータに対してのvalidateを行ってから保存処理を行うが、validate処理時にまだArticle.category_idが割り当てられていないためにValidationエラーが発生する。なので下記のように設定してみる。
$this->Article->saveAll($data, array('validate' => true));
validateのタイミングが各レコードの更新直前に変わり、category_idが割り当てられた上でvalidateされるのでvalidateエラーが発生しない。ただし、レコードを更新しながらvalidateを行うので途中で何らかのvalidateエラーが発生した場合は直前まで保存したレコードにロールバック処理が発生する。大量に更新するのであれば自分で事前にcategory_idを割り当てておくべきかもしれない。
もう一点注意が必要な挙動を発見した。
saveAllで'validate' => trueを設定しているとvalidateでエラーが発生してもなぜかsaveAllが真値を返してしまう。つまり下記の処理は
validateエラーが発生しても必ずtrueを返してしまう。
if($this->Article->saveAll($data, array('validate' => true))) {
return true;
} else {
return false;
}
validateErrorsにはエラーメッセージが格納されるので下記のような処理にするといいかもしれない。
if (!empty($this->Article->validationErrors)
&& $this->Article->saveAll($data, array('validate' => true))) {
return true;
} else {
return false;
}
コメント
はじめまして、Google検索結果から飛んできました! 「
はじめまして、Google検索結果から飛んできました!
「1.同一モデルの複数レコードの保存」ですが、
$this->Article->saveAll($data);
ではなく、
$this->Article->saveAll($data['Article']);
ではないでしょうか?
僕のほうでも少しハマってしまったのですが、調べてみると後者のようにしないと複数レコードを一括保存できませんでした。
参考にしていただければ幸いです!
遅くなりました。 コメントありがとうございます。 ここ最近
遅くなりました。
コメントありがとうございます。
ここ最近プログラムから離れてしまっていて、もう忘れてしまっていました。。。
今度開発するとき参考にさせていただきます。
ですよねー cookbookのsaveAllの項目にはAr
ですよねー
cookbookのsaveAllの項目にはArticleを含む連想配列を第1引数に渡すような例が書かれていますが、
実際には、本文中にあるように
> 単一のモデルに複数のレコードを保存するためには、$data は整数のインデックスがついた配列である必要があります。
としないと更新してくれないですねぇ。
新しいコメントの投稿