The Cart_product table has 4 columns:
id | cart_id | product_id | size_id | quantity
with relationship of belongsToMany
for Cart
, Product
and Size
.
User can add a product with deferent sizes but not same size, so product->id = 1 can have size->id = 1 and size->id = 2.
I want to sync product->id and size->id where only have 1 row of same product->id and size->id.
with this code, only my product->id is synced.
$this->cart->products()->syncWithoutDetaching(
[$product->id => ['size_id' => $size->id, 'quantity' => $quantity]]
);
As I said I need to sync product->id and size->id, I can have a product with deferent sizes:
id | cart_id | product_id | size_id | quantity
1 | 1 |1 | 2 |2
2 | 1 |1 | 3 |1
but not a product with same sizes:
id | cart_id | product_id | size_id | quantity
1 | 1 |1 | 2 |2
2 | 1 |1 | 2 |1
I have checked many cases as :
$this->cart->products()->syncWithoutDetaching(
[$product->id, $size->id => ['quantity' => $quantity]]
);
But it can't take true result!
CodePudding user response:
BelongsToMany relation are made for pivot tables with only two foreign keys as their unicity index. In your case, the unicity is obtained with three indexes cart_id
, product_id
and size_id
so you can't use any predefined method from the relation to achieve your goal.
side note: I suggest you add this constraint in your database so it triggers an error if your code tries to insert two rows with the same values in those indexes
To sync with three indexes I suggest you use updateOrInsert()
or upsert()
\DB::table('your_pivot_table_name')->updateOrInsert(
['cart_id' => 1, 'product_id' => 1, 'size_id' => 2], //the unique index to look out for
['quantity' => 2] //the other fields to sync
);
Another idea would be to declare the pivot table as Custom Intermediate Table Models and add the method to "sync" using updateOrCreate()
to it.
EDIT: upsert
DB::table('cart_product')->upsert(
[
[ 'cart_id' => $this->instance()->id, 'product_id' => $product->id, 'size_id' => $size->id, 'quantity' => (int) $qunatity]
],
['cart_id', 'product_id', 'size_id'],
['quantity']
);