Reputation: 1792
I have a some models related to eachother like this:
Order
- hasMany(CartItem)
- hasManyThrough(Product, CartItem)
CartItem
- belongsTo(Order)
- hasOne(Product)
Product
- belongsTo(CartItem)
All of the relationships are verified to be working by calling both the dynamic property and the method form (e.g. $order->products
and $order->products()
for an Order model)
Now I'd like to delete all products related to a specific order, so I tried this (with order ID = 3):
Order::find(3)->products()->delete()
However this isn't working. For one reason or the other I get the error message stating the joining column could not be found:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'cart_items.order_id' in 'where clause' (SQL: delete from `products` where `cart_items`.`order_id` = 3)
The raw SQL output (using toSql()
) does however include the join...
Anyone knows what's wrong here?
Upvotes: 2
Views: 1361
Reputation: 81167
Query Builder delete method() works a bit defferently to other methods, thus it mutates the query and there is no join - it simply takes 'wheres' and ommits other parts of the builder. That being said to achieve what you want use one of these:
// This will run delete query for every product
Order::find(3)->products->each(function ($product) {
$product->delete();
});
// This will run only single query for all of them, which is obviously faster
$productsIds = Order::find(3)->products->modelKeys();
Product::whereIn('id', $productsIds)->delete();
Mind that both methods remove rows from the DB but don't remove models from the Collection:
$order = Order::find(3);
// run deletes
$order->products; // Collection still contains all the models!
Upvotes: 6