I have many to many reltionship, trying to update the pivot table order_services.
I have this update function in my conroller:
$order->update($data);
$order->services()->detach();
foreach ($request->services as $service) {
$order->services()->attach($service['service'], [
'quantity' => $service['quantity'],
'price' => $service['price'],
'total' => $service['total']
]);
}
blade page:
<div class="flex">
<button class="mx-1 mt-1 btn btn-primary"
type="button" @click="adjustBy(o,-1)">-</button>
<input type="hidden" x-bind:name="`services[${index}][service]`" :value="o.id">
=
<input type="number" min="1" class="input"
{{--name="quantity[]"--}}
x-bind:name="`services[${index}][quantity]`"
:value="o.quantity"/>
<button class="mx-1 mt-1 btn btn-primary" type="button" @click="adjustBy(o, 1)"> </button>
</div>
<div class="mx-1" x-text="o.total"></div>
<input type="hidden" x-bind:name="`services[${index}][price]`" :value="o.total">
<input type="hidden" x-bind:name="`services[${index}][total]`" :value="o.total">
<div>
The problem with this code it delete a previos and atach a new value only even when I didn't delete the previos value.
How can I fix the code to print old value (if didnt deleted) and new value.
Can any one help?
CodePudding user response:
In your code example you're firstly deleting all your OrderService pivot records.
When trying to add (via attach function) new pivot records, from your comment we can see you're passing NULL value instead of service id in attach function. This will fail since it's required to pass and item ID.
If your $request
data contains all services that should be related to your updated order, you can use sync() in order to save your new data. This way you can:
- delete pivot records that are not present in the
$request
, - keep existing that are present
- and add new ones that are also present in the
$request
.
If you do not want to delete pivot records that are not present in the $request
, and you only want to add new ones and update existing records, you can use syncWithoutDetaching()
instead.
$order->services()->sync([
1 => ['quantity' => 1, 'price' => 3, 'total' => 3],
2 => ['quantity' => 3, 'price' => 4, 'total' => 12]
]);
You can prepare your sync object before actually syncing
$syncObject = [];
foreach ($request['services'] as $service) {
$syncObject[$service['id']] = [
'quantity' => $service['quantity'],
'price' => $service['price'],
'total' => $service['total']
];
}
And then
$order->services()->sync($syncObject);