想定としては、一つの注文(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
がなければ新規追加になる。