我想在更新订单时更新特定的 order_product 行。
如果我有多个产品在同一订单中具有相同的 ID,但颜色和数量不同。
order_product
桌子
id | 订单_id | 产品_id | 颜色 | 数量 |
---|---|---|---|---|
1 | 1 | 1 | 红色 | 2 |
2 | 1 | 1 | 蓝色 | 1 |
我正在尝试使用
updateExistingPivot()
,但它会像最后一个一样更新记录。
这是我更新订单时发送的正文的样子:
{
"products": [
{
"id": 1,
"color": "red",
"quantity": 1
},
{
"id": 1,
"color": "blue",
"quantity": 3
},
{
"id": 2,
"color": "black",
"quantity": 5
}
]}
这正是我所期望看到的
id | 订单_id | 产品_id | 颜色 | 数量 |
---|---|---|---|---|
1 | 1 | 1 | 红色 | 1 |
2 | 1 | 1 | 蓝色 | 3 |
3 | 1 | 2 | 黑色 | 5 |
相反,得到了这个
id | 订单_id | 产品_id | 颜色 | 数量 |
---|---|---|---|---|
1 | 1 | 1 | 蓝色 | 3 |
2 | 1 | 1 | 蓝色 | 3 |
3 | 1 | 2 | 黑色 | 5 |
OrdersController
public function update(AdminUpdateOrderRequest $request, $id)
{
$orderValidated = $request->validated();
$order = Order::findOrFail($id);
$order->update($orderValidated);
foreach ($orderValidated['products'] as $product) {
$order->products()->updateExistingPivot(
$product['id'], [
'color' => $product['color'],
'quantity' => $product['quantity'],
]
);
}
return OrderResource::make($order)->additional([
'success' => true,
]);
}
OrderModel
public function products()
{
return $this->belongsToMany(Product::class)->withPivot(['color', 'quantity', 'id'])->withTimestamps();
}
首先要做的事情:多对多关系的数据透视表必须始终在两个模型 ID 上定义唯一的组合索引。 让我们看一下 Laravel 的扩展生成器如何定义用户和角色之间的数据透视表的示例:
Schema::create('role_user', function (Blueprint $table) {
$table->unsignedBigInteger('role_id')->index();
$table->foreign('role_id')->references('id')->on('role')->onDelete('cascade');
$table->unsignedBigInteger('user_id')->index();
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
$table->primary(['role_id', 'user_id']);
});
看到主要定义了吗?这样可以确保“role_id”和“user_id”之间的任何组合都是唯一的。
在该示例(用户、角色)中,如果我们的数据透视表中有一些额外的列,我们将使用 updateExistingPivot() 两种方式:
$user->roles()->updateExistingPivot($role->id, [cols => values]);
$role->users()->updateExistingPivot($user->id, [cols => values]);