一次保存多个关联的实体Cakephp
问题描述:
我已经订购了一个订单,但是每个订单的多个订单(产品和总价格,数量)并不与订单一起保存。一次保存多个关联的实体Cakephp
这是现阶段的日志转储:
{ "associated": [ "Orderlines", "Payments" ], "Orderlines": [ { "total_cost": "222.44", "total_quantity": "2", "product_variants_id": "34" }, { "total_cost": "154", "total_quantity": "2", "product_variants_id": "33" } ], "users_id": 1, "usersaddress_id": 1, "orderstatus": 0, "date": "2017-09-21T01:53:38+00:00", "last_modified": "2017-09-21T01:53:38+00:00" }
控制器:
$associated = ['Orderlines', 'Payments'];
$order = $this->Orders->newEntity(['associated'=>$associated]);
if ($this->request->is('post')) {
$order = $this->Orders->patchEntity($order, $this->request->getData());
$order->users_id = $this->Auth->user('id');
//Hardcoded the SHU MART stores location because thats all thats gonna get implemented for now
$order->usersaddress_id = 1;
$order->orderstatus = 0;
$order->date = Time::now();
$order->last_modified = Time::now();
//god this is ugly. forgive me for i have sinned
$order->setDirty('users_id', true);
$order->setDirty('usersaddress_id', true);
$order->setDirty('date', true);
$order->setDirty('last_modified', true);
$order->setDirty('orderlines', true);
if ($this->Orders->save($order)) {
$this->Flash->success(__('The order has been saved.'));
return $this->redirect(['controller'=>'orderlines','action' => 'index']);
}
$this->Flash->error(__('The order could not be saved. Please, try again.'));
}
和订单项目循环内形式:
<?php
echo $this->Form->control('Orderlines.'.$orderLineIndex.'.total_cost',
['label'=>'', 'value'=>$product_total
, 'type'=>'hidden'
]);
?>
<?php
echo $this->Form->control('Orderlines.'.$orderLineIndex.'.total_quantity',
['label'=>'', 'value'=>$item['quantity']
, 'type'=>'hidden'
]);
?>
<?php
echo $this->Form->control('Orderlines.'.$orderLineIndex.'.product_variants_id',
['label'=>'', 'value'=>$item['id']
, 'type'=>'hidden'
]);
?>
现在我已经试过了没有Orderlines.
在开始,并试图单独保存每个订单,但它不会保存订单我d和东西。
我只是想能够一次性保存它。例如:
order{ id, x, y, orderlines[[0]{OL1...}[1]{OL2}] }
因此,我可以在订单中包含尽可能多的订单并将它们全部保存在一起。我想我只是缺少一个小的语法,但也许我不是。
public 'associated' =>
array (size=2)
0 => string 'Orderlines' (length=10)
1 => string 'Payments' (length=8)
public 'orderlines' =>
array (size=3)
0 =>
object(App\Model\Entity\Orderline)[349]
public 'total_cost' => float 40.28
public 'total_quantity' => int 1
public 'product_variants_id' => int 679
public '[new]' => boolean true
public '[accessible]' =>
array (size=2)
...
public '[dirty]' =>
array (size=3)
...
public '[original]' =>
array (size=0)
...
public '[virtual]' =>
array (size=0)
...
public '[errors]' =>
array (size=0)
...
public '[invalid]' =>
array (size=0)
...
public '[repository]' => string 'Orderlines' (length=10)
1 =>
object(App\Model\Entity\Orderline)[375]
public 'total_cost' => float 66
public 'total_quantity' => int 2
public 'product_variants_id' => int 55
public '[new]' => boolean true
public '[accessible]' =>
array (size=2)
...
public '[dirty]' =>
array (size=3)
...
public '[original]' =>
array (size=0)
...
public '[virtual]' =>
array (size=0)
...
public '[errors]' =>
array (size=0)
...
public '[invalid]' =>
array (size=0)
...
public '[repository]' => string 'Orderlines' (length=10)
2 =>
object(App\Model\Entity\Orderline)[347]
public 'total_cost' => float 222.44
public 'total_quantity' => int 2
public 'product_variants_id' => int 34
public '[new]' => boolean true
public '[accessible]' =>
array (size=2)
...
public '[dirty]' =>
array (size=3)
...
public '[original]' =>
array (size=0)
...
public '[virtual]' =>
array (size=0)
...
public '[errors]' =>
array (size=0)
...
public '[invalid]' =>
array (size=0)
...
public '[repository]' => string 'Orderlines' (length=10)
public 'users_id' => int 1
public 'usersaddress_id' => int 1
public 'orderstatus' => int 0
public 'date' =>
object(Cake\I18n\Time)[327]
public 'time' => string '2017-09-27T21:12:38+10:00' (length=25)
public 'timezone' => string 'Australia/Melbourne' (length=19)
public 'fixedNowTime' => boolean false
public 'last_modified' =>
object(Cake\I18n\Time)[350]
public 'time' => string '2017-09-27T21:12:38+10:00' (length=25)
public 'timezone' => string 'Australia/Melbourne' (length=19)
public 'fixedNowTime' => boolean false
public '[new]' => boolean true
public '[accessible]' =>
array (size=3)
'*' => boolean true
'id' => boolean false
'users_id' => boolean false
public '[dirty]' =>
array (size=7)
'associated' => boolean true
'orderlines' => boolean true
'users_id' => boolean true
'usersaddress_id' => boolean true
'orderstatus' => boolean true
'date' => boolean true
'last_modified' => boolean true
public '[original]' =>
array (size=1)
'orderlines' =>
array (size=3)
0 =>
object(App\Model\Entity\Orderline)[359]
...
1 =>
object(App\Model\Entity\Orderline)[372]
...
2 =>
object(App\Model\Entity\Orderline)[346]
...
public '[virtual]' =>
array (size=0)
empty
public '[errors]' =>
array (size=0)
empty
public '[invalid]' =>
array (size=0)
empty
public '[repository]' => string 'Orders' (length=6)
谢谢。
答
所以我有2个答案。第一个是真正的杂乱无章的解决方案,以及我后来发现的解决方案。
if ($result) {
$orderlinescontroller = new OrderlinesController();
if ($orderlinescontroller->addAllFromCart($result->id)) {
$this->Flash->success(__('The order ' . $result->id . ' has been successfully placed'));
$this->clearUsersCart($this->Auth->user('id'));
所以先保存订单,然后创建一个需要保存多个关联项的控制器实例。然后,我创建了一个函数,查看购物车项目的db/session变量以将它们保存在订单中。
public function addAllFromCart($order_id)
{
$success = true;
$cart_items = $this->getCartItemsArray();
$saved_ids = [];
foreach ($cart_items as $cart) {
$this->log($cart);
$orderline = $this->makeEntity($order_id, $cart);
$new = $this->Orderlines->save($orderline);
if ($new) {
$this->log('Line saved');
array_push($saved_ids, $new->id);
} else {
$this->log('Line save FAILED');
$success = false;
//if there is a failure, we need to delete the lines that we made - there is a better way, but cake sucks and conventions don't work
foreach ($saved_ids as $id_to_delete) {
$d = $this->Orderlines->get($id_to_delete);
$this->Orderlines->delete($d);
}
}
}
$this->log('WAS ADD ALL FROM CART A SUCCESS? -- ' . $success);
// if ($success) {
// return $this->redirect($this->referer());
// } else {
// return $this->redirect($this->referer());
// }
return $success;
}
`
这完全是超级混乱和un-cake-ey,但它的工作原理。另一种解决方案是当我重新访问添加产品的一部分时发现的,它是如何明确告诉save()要保存什么关联的。因此使用了下面的内容。
$result = $this->Orders->save($save, ['associated' => ['Orderlines']]);
关联属性默认情况下小写,并强调除非明确配置,否则,即'Orderlines!= orderlines'。 – ndm
我担心没有工作,我做了一些改变,现在创建多个订单行实体并将其放入订单中。请找到编辑到帖子中的$ order的'var_dump'。我确定它的东西真的很少! – mewc