Laravel:如何使用 foreach 循环根据订单数量减少库存

问题描述

我无法根据数据透视表 quantity 获取已订购产品的 stock 以更新 order_items 数量

订单模型

public function items()
{
    return $this->belongsToMany(Product::class,'order_items','order_id','product_id')->withPivot('quantity','price')->withTimestamps();
}

订单项模型

public function product()
{
    return $this->belongsTo(Product::class);
}

产品型号

public function orders()
{
    return $this->belongsToMany(Order::class,'price')->withTimestamps();
}

OrderController(更新)

public function store(Request $request)
{
    $order = new Order();
    $order->order_number = uniqid('Order #');
    ...
    $order->save();
    
    $cartItems = \Cart::session(auth()->id())->getContent();
    foreach ($cartItems as $item)
    {
        $order->items()->attach($item->id,[
            'price'=> $item->price,'quantity'=> $item->quantity
        ]);
    }

    // Update stock quantity
    foreach ($order->items as $prod) {
    {
        dd($order->items);
        $newStock = $prod->stock - $item->quantity;
        $prod->update(['stock' => $newStock]);
    }
    
    ...

}
Illuminate\Database\Eloquent\Collection {#598 ▼
  #items: array:2 [▼
    0 => App\Models\Product {#1159 ▶}
    1 => App\Models\Product {#754 ▼
      #table: "products"
      #translatable: array:17 [▶]
      #fillable: array:6 [▶]
      #connection: "MysqL"
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:16 [▼
        "id" => 24
        "shop_id" => 1
        "cat_id" => 19
        "child_cat_id" => 5
        "name" => "Facilis sit SAEpe."
        "slug" => "voluptatum-rem-doloribus-eligendi-porro-molestiae-sapiente-ut-aut"
        "summary" => "Quidem repudiandae voluptate explicabo sed voluptates impedit explicabo vel quis."
        "description" => "Sint corporis sed velit velit. Qui qui quibusdam sint. Commodi facere similique voluptas commodi rerum omnis incidunt qui. Est exercitationem odit id dignissimo ▶"
        "image" => "https://via.placeholder.com/400x200.png/007799?text=corrupti"
        "images" => "https://via.placeholder.com/400x200.png/00ccaa?text=nihil"
        "price" => 67.24
        "stock" => 4  // Product stock
        "condition" => "popular"
        "publish" => 1
        "created_at" => "2021-04-26 20:21:42"
        "updated_at" => "2021-04-26 20:21:42"
      ]
      #original: array:22 [▶]
      #changes: []
      #casts: []
      #classCastCache: []
      #dates: []
      #dateFormat: null
      #appends: []
      #dispatchesEvents: []
      #observables: []
      #relations: array:1 [▶]
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #guarded: array:1 [▶]
    }
  ]
}

解决方法

您无需在 foreach 中查询您的数据库来获取当前的 Product,因为您已经可以在您的 items 上访问它。

您可以使用经典的 foreach,也可以在 items 集合上使用 each 方法。

public function store(Request $request)
{
    // ...

    // iterate (loop) over each item in the order items collection
    $order->items->each(function ($item) {
        // deduct the quantity of the item for this order
        // from the stock of the product and update the new stock
        $item->update(['stock' => ($item->stock - $item->pivot->quantity)]);
    });

    // ...
}

顺便提一下,尽量在命名和使用框架约定方面保持一致。您有一个名为 Product 的模型,但您将 Product 的实例称为 $item。我知道这似乎是一件很小的事情,但是,请考虑一个新开发人员或从未见过您的代码的人,或者您在 6 个月内返回代码并看到 $item 然后期望找到一个 Item 模型.

,

可能会导致控制器内部出现问题的几件事。

试试下面的代码,看看它是否适合你。

  • 删除了 $order->items() 中的括号
  • $prod 查询从 get 更改为 first
    • Get 返回一组结果,第一个将返回一个。

更新了我的答案

public function store(Request $request)
{
    ....

    // Update stock quantity
    foreach ($order->items as $prod)
    {
        $newStock = $item->stock - $item->pivot->quantity;
        $prod->update(['stock' => $newStock]);
    }
    
    ...

}