简体   繁体   English

一次性保存多个关联实体Cakephp

[英]Save multiple associated entities in one go Cakephp

i've an Order that saves, but the multiple orderlines (a product and total price, quantity) for each order isnt saving together with the order. 我有一个保存的订单,但是每个订单的多个订单行(产品和总价格,数量)没有与订单一起保存。

Here is the log dump at this stage: 这是现阶段的日志转储:

{ "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" }

Controller: 控制器:

$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.'));
    }

and the form inside the orderline loop: 以及订单线循环中的表单:

 <?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'
                        ]);
                    ?>

Now i've tried it without Orderlines. 现在,我已经尝试过没有Orderlines. at the start, and tried saving each orderline individually but it wont save the order id and stuff. 在开始时,尝试单独保存每个订单行,但不会保存订单ID和商品。

I just want to be able to save it in one go. 我只希望能够一次性保存它。 Something like: 就像是:

order{ id, x, y, orderlines[[0]{OL1...}[1]{OL2}] }  

So i can have as many orderlines in an order and save them all together each time. 因此,我可以在订单中包含尽可能多的订单行,并且每次都将它们保存在一起。 I think im just missing a small syntax thing, but maybe im not. 我认为我只是缺少一个小的语法问题,但也许不是。

    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)

Thanks. 谢谢。

So there are 2 answers i got. 所以我有2个答案。 The first being the really-messy-but-works solution, and the one i found later. 第一个是真正混乱但可行的解决方案,后来我找到了。

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'));

so first you save the order, then create an instance of the controller of the associated item you need to save multiple of. 因此,首先保存订单,然后为您需要保存多个关联项目的控制器创建一个实例。 Then i created a function that looks at the db/session variables for the cart items to save them with the order. 然后,我创建了一个查看购物车项目的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;
    }
`

which altogether is super messy and un-cake-ey but it works. 这完全是超级混乱和松糕的家伙,但它的工作原理。 The other solution i found out much later when i revisited a part of adding products, was how it explicitly told save() what associations to save. 当我重新讨论添加产品的一部分时,我发现的另一种解决方案是它如何显式地告诉save()保存哪些关联。 Hence the below was used. 因此,使用以下内容。

$result = $this->Orders->save($save, ['associated' => ['Orderlines']]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM