英文:
Sync command wont update values
问题
你好,这是你的代码,其中包含了一些问题。在使用sync
命令时,它会更新现有的many-to-many
关系表,但似乎出现了错误。下面是你的代码中的问题描述:
问题在于,当你使用sync
方法时,它会用提供的数据替换已存在的关系数据,而不是累加它们。因此,如果你尝试更新现有的产品数量,它将替换原来的数量而不是累加。
在你的代码中,你通过以下方式来更新产品数量:
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
这会更新产品的数量,但不会考虑已存在的关系数据。因此,当你使用sync
方法时,它会用新的数据来替换原来的数据。
如果你想要累加产品的数量,你需要修改你的代码,以便在更新产品数量时考虑已存在的关系数据。你可以尝试以下的修改:
foreach ($request->productOrder as $product) {
$values[$product['product_id']] = [
'amount' => $product['amount'],
];
}
$order->products()->syncWithoutDetaching($values);
这里使用syncWithoutDetaching
方法来更新关系数据而不替换它们。这将根据产品的ID更新数量,而不是替换整个关系。这样,你可以累加产品数量而不会丢失已存在的关系数据。
请确保在做出这些修改之前进行适当的测试,以确保它们满足你的需求。
英文:
Hello i have this code in Laravel
that updates existing many-to-many
relationship tables so when i use the sync
command the values update wrong, this is the code:
public function update(Request $request, $id)
{
$order = Order::where('id', $id)->first();
$request->validate([
'order_number' => 'required',
'client_id' => 'required',
'description' => 'required',
'productOrder' => 'required',
'productOrder.*.product_id' => 'required|distinct|exists:products,id',
'productOrder.*.amount' => 'required|numeric|min:1',
]);
$order->update($request->all());
foreach ($request->productOrder as $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product['product_id'],
'amount' => $product['amount'],
];
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
}
$order->products()->sync($values); //the problem is here
$orders = Order::all();
$orders->load('client', 'products');
return view('orders/index', compact('orders'));
}
If i have 2 values like:
Product1 -> amount: 250
Product2 -> 100
And i updatet these existing values to
Product1 -> amount: 350
Product2 -> 200
The result will be
Product2 -> 200
Product2 -> 200
If i make this line of code dd($order->products()->sync($values));
i get this result
If i add a new product with the existing ones i get this result
From what im understanding the first result is replaced with the second one or removed, why does this happen?
答案1
得分: 1
这段代码存在的问题是,sync
函数获取到错误的 ID,因为 $values
中包含了数字自增的 ID,例如:0
, 1
, 2
等。
你需要传递给 sync
的是一个 ID 数组 [1, 2, 3]
,或者是一个数组的数组(当你想要更新与该 ID 相关的列时,例如:[1 => ['amount' => 100], 2, 3]
)。
让我尝试修改你的代码以帮助你。
假设你有 orders
表和 products
表。你还有一个名为 order_product
的中间表,用于存储它们之间的关系。这个 order_product
表包括以下字段:
id
order_id
product_id
amount
那么,你的代码应该像这样:
public function update(Request $request, $id)
{
$validated = $request->validate([
'order_number' => 'required',
'client_id' => 'required',
'description' => 'required',
'productOrder' => 'required',
'productOrder.*.product_id' => 'required|distinct|exists:products,id',
'productOrder.*.amount' => 'required|numeric|min:1',
]);
$order = Order::find($id); // 我建议改为使用隐式绑定
$order->update($validated); // 不要使用 $request->all(),这将包含未经验证的值
foreach ($request->productOrder as $product) {
$values[$product['product_id']] = [
'amount' => $product['amount']
];
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
}
$order->products()->sync($values); // 现在它将正常工作
$orders = Order::all();
$orders->load('client', 'products');
return view('orders/index', compact('orders'));
}
希望这有助于解决你的问题。
英文:
So, you have this code:
public function update(Request $request, $id)
{
$order = Order::where('id', $id)->first();
$request->validate([
'order_number' => 'required',
'client_id' => 'required',
'description' => 'required',
'productOrder' => 'required',
'productOrder.*.product_id' => 'required|distinct|exists:products,id',
'productOrder.*.amount' => 'required|numeric|min:1',
]);
$order->update($request->all());
foreach ($request->productOrder as $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product['product_id'],
'amount' => $product['amount'],
];
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
}
$order->products()->sync($values); //the problem is here
$orders = Order::all();
$orders->load('client', 'products');
return view('orders/index', compact('orders'));
}
The issue with it, is that sync
is getting wrong IDs, because $values
has numeric autoincrementals IDs: 0
, 1
, 2
, etc.
What you need to pass to the sync
is either an array of IDs [1, 2, 3]
, or an array of arrays (when you want to update columns related to that ID, for example: [1 => ['amount' => 100], 2, 3]
.
Let me try to modify your code to help you.
Let's assume you orders
table and products
table. You also have a pivot table called order_product
table, so you store the relation in there. This order_product
table has:
id
order_id
product_id
amount
So, your code should be like this:
public function update(Request $request, $id)
{
$validated = $request->validate([
'order_number' => 'required',
'client_id' => 'required',
'description' => 'required',
'productOrder' => 'required',
'productOrder.*.product_id' => 'required|distinct|exists:products,id',
'productOrder.*.amount' => 'required|numeric|min:1',
]);
$order = Order::find($id); // I would change this to use implicit binding
$order->update($validated); // Don't use $request->all(), you are using unvalidated values
foreach ($request->productOrder as $product) {
$values[$product['product_id']] = [
'amount' => $product['amount']
];
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
}
$order->products()->sync($values); // Now it will work
$orders = Order::all();
$orders->load('client', 'products');
return view('orders/index', compact('orders'));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论