アソシエーションされたモデルを一括で保存する方法と、うまくいかない時の対処法。

Shunsuke Sawada

cake-logo

ちゃんとマニュアル読めよって話ですね。

マニュアル:データを保存する

環境:CakePHP 2.3.5

1
2
3
4
5
6
7
8
9
$data = array(
    'Article' => array('title' => 'My first article'),
    'Comment' => array(
        array('body' => 'Comment 1', 'user_id' => 1),
        array('body' => 'Save a new user as well', 'User' => array('first' => 'mad', 'last' => 'coder')),
    ),
);

$this->Article->saveAssociated($data, array('deep' => true));

deepを指定すると深い階層まで保存してくれます。

でも保存されない時

あるよねーそういう時。

配列が正しくできているか

debug($this->request->data);でまずは確認。
ちゃんとsaveできるような配列の形ができているでしょうか。

バリデーションを疑う
自分で設定したバリデーションに引っかかっているという間抜けなオチもしばしば。
$this->Model->save($this->request->data, array('validate' => false));
とすると、そのsaveではバリデーション無効化。

キャッシュを疑う
tmp/chache/modelsの下のキャッシュファイルを削除
これはまだ遭遇したことないけど、あるらしい。

ループを疑う
これは結構きづかない。
アソシエーションが深くなると、なんだかループしちゃったみたいな時。

A hasMany B
  B hasMany C
    C hasMany D
      D hasOne A

みたいなね。D の A_id が保存できない。

[googlead]

1
2
3
$this->request->data[A][B][C][D][id] = 1;
$this->request->data[A][B][C][D][A_id] = 123;
$this->A->save($this->request->data[A]);

↑上みたいにやってもだめだった。

せっかくsaveAssociated の deep を覚えたので、
一回で保存しちゃいたいとこだけど、できません。エラーも出ません。
しれ〜っと保存できたふりして、データベース確認すると保存されていな…。

Aのid と DのA_id が競合してるのかなんなのか。
でも何となくは想像できるよね。

なので、

1
2
3
$this->request->data[D][id];
$this->request->data[D][A_id];
$this->D->save($this->request->data[D]);

って、別にしてやればOKです。
ちょっとめんどくさいけどね。

3
Shunsuke Sawada

おすすめの記事

CakePHP 2.x JSヘルパーでajax通信(ajax helperは使わない)
20
Rails4でQiita投稿ボタンをつくった
18
紙のデザイナーがウェブ開発できるようになるまでに必要なこと
451