phplaravelmass-assignment

Laravel DB update on primary keys works with a raw array but not with a variable


I initially wanted to use Eloquent:

$product->quantity_discounts()
->where('min_amount', $discount['min_amount'])
->where('user_id', $discount['user_id'])
->where('group_id', $discount['group_id'])
->update($discount);

but Eloquent doesn't support composite primary keys (https://github.com/laravel/framework/issues/5355).

My code, using the query builder:

DB::table('quantity_discounts')
->where('min_amount', $discount['min_amount'])
->where('user_id', $discount['user_id'])
->where('group_id', $discount['group_id'])
->where('product_id', $id)
->update($discount);

$discount:

[
    "min_amount" => "2",
    "price" => "20",
    "user_id" => "1",
    "group_id" => "0"
]

The only field that gets changed is the price. All the other fields are part of a primary key constraint.

enter image description here

However, passing exactly what's inside $discount works. It seems like the query builder won't mass assign values to primary keys.

Query for update($discount):

update `quantity_discounts` set `min_amount` = ?, `price` = ?, `user_id` = ?, `group_id` = ? where `min_amount` = ? and `user_id` = ? and `group_id` = ? and `product_id` = ?

Query for update([...]):

update `quantity_discounts` set `min_amount` = ?, `price` = ?, `user_id` = ?, `group_id` = ? where `min_amount` = ? and `user_id` = ? and `group_id` = ? and `product_id` = ? 

The queries are identical. The arrays are identical. [] works but $discount doesn't.

If any primary key field is changed, the price won't be changed either. Nothing will be changed. If only price is changed, price will change.

enter image description here

Though using a raw array [] works:

enter image description here

And the arrays are indeed identical:

enter image description here

Could this be some sort of mass assignment protection? ["min_amount" => $discount["min_amount"], ...] didn't work either. I have set all fields to be $fillable, but that's for Eloquent, not the query builder.


Solution

  • in the case on variable $discount I see a logical error that could be the reason, you are looking for the new ids and not for the old ones, if the product only has one discount then the update does not work because does not exist the discount with the new ids, but if you only change the price or amount the update works because the ids did not change, so you need search by the old ids and update with the variable $discount.

    DB::table('quantity_discounts')
    ->where('min_amount', $discount['min_amount'])
    ->where('user_id', $old['user_id'])
    ->where('group_id', $old['group_id'])
    ->where('product_id', $id)
    ->update($discount);
    

    I hope this helps you!