同步命令不会更新数值

huangapple go评论59阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月8日 17:50:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383953.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定