LoginSignup
34
33

More than 5 years have passed since last update.

CakePHP3でアソシエーションごとsaveする

Last updated at Posted at 2015-06-23

想定としては、一つの注文(Orders)に複数の商品(Items)が紐付いているようなデータ。
一つの登録画面で注文テーブルに保存する内容と注文明細テーブルに保存する内容を両方入力させてそのまままとめて保存したい。

モデル。

OrdersTable.php のイニシャライズのところにhasmany追加。

    public function initialize(array $config)
    {
        $this->hasMany('Items', [
            'foreignKey' => 'order_id'
        ]);
    }

テンプレートは以下のように、Ordersの方のフォームはそのまま、Itemsの方は items.0.name というようにする。
もちろん0番目、1番目、という意味。

        <?php
            echo $this->Form->input('order_date');

            echo $this->Form->input('items.0.item_name');
            echo $this->Form->input('items.0.item_price');
            echo $this->Form->input('items.0.qty');
        ?>

あとはbakeしたコントローラのpostのとこにassociatedを追加するだけ。

        if ($this->request->is('post')) {
            $order = $this->Orders->patchEntity($order, $this->request->data, ['associated' => ['Items']]);
            if ($this->Orders->save($order)) {
                $this->Flash->success(__('The order has been saved.'));
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The order could not be saved. Please, try again.'));
            }
        }

ここまではいい。問題ない。
問題なのはitemsテーブルとかじゃなくて、order_detailsみたいな単語連結型のテーブル名の時だ。
モデルはいいよね。OrderDetails 以外にあり得ない。
じゃあ、テンプレートのところ、
items.0.name となっている部分はどう書けばいいのか?

order_details.0.name

とするのだ。。

編集のとき

ちなみに、編集のときは、

[
    'items' => [
        (int) 0 => [
            'id' => '10' // <- NEW!
            'item_name' => 'aaa'
            'item_price' => '100'
            'qty' => 'hoge'
        ],
    ]
]

という風に、 id を一緒に渡してあげればよい。

つまり、id があれば上書き、 id がなければ新規追加になる。

34
33
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
33