-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eloquent Model delete/deleting events are not triggered on a where(...)->delete() #2536
Comments
Yes, this is basically expected. In order to fire the events we would have to pull the models first and then call the events with the model instances. Then call the delete query. |
Issue laravel#2536 fixed an issue where URL::to() couldn't be used to create http URLs from an https page. This is a fix to a similar but different issue where URL::route() also can't be used to create routes that are http if the current page is https. In order to properly fix this issue with consistency for Laravel route design, it was necessary to add an "http" route option (an "https" option already existed, but there was no "http" option). So with this commit, it is now possible to specify 'http' in a route declaration, which behaves exactly as the 'https' option does, forcing generated route URLs to use http, and only responding to http requests for the route.
Issue laravel#2536 fixed an issue where URL::to() couldn't be used to create http URLs from an https page. This is a fix to a similar but different issue where URL::route() can't be used to create routes to URLs that are http if the current page is https. In order to properly fix this issue with consistency for the current route design, it was necessary to add an 'http' option to the route actions (an 'https' option already existed). So with this commit it is now possible to specify 'http' in a route declaration, which behaves exactly as the 'https' option does, forcing generated route URLs to use http, and only responding to http requests for that route.
Is there a workaround? |
Just to be clear, I wouldn't say you need a "workaround" since this isn't a bug, it really does make sense when you understand what's going on. The solution you need to use instead depends on what you're trying to do. First, let's talk about their first example:
All this actually does is execute SQL, probably something like "DELETE FROM analytic WHERE id=2". That's it. It doesn't load the models into memory, etc. For these kinds of functions, Laravel is just passing control to an underlying Query Builder query that performs the actions in SQL. That's just something that Eloquent lets you do, it lets you perform Query actions directly on its underlying query object. In order to trigger events when you delete something, the Eloquent model would have to be loaded into memory, and then delete() has to be called on each model individually. This is an entirely different kind of operation. The question gives you an example of how to do that for one object with the ID "2":
In this case "first()" loads the model into memory, and then the delete() function is called on it. If you have more than one row/object that you want to delete at a time, you can do something like this (be careful with the where() statements, you don't want to delete things you don't want to!):
Here's another way to do the same thing using Laravel's each() function that it gives you for working on Collections...
|
I have something similar and still consider it somewhat confusing to say the least. I have a typical event hook for soft deleting children: public static function boot()
{
parent::boot();
static::deleted(function($model1)
{
$model1->hasmanyrelation()->delete();
});
} and public function hasmanyrelation()
{
return $this->hasMany('Model2');
} Now when I use:
things work as expected and model2 children of model 1 get (soft) deleted. But when I use:
then all related model1 records get deleted but model2 and all its records remain untouched. |
thank u my problem is fix |
@orrd Thanks for explanation! |
@silverdr, yes that is the expected behavior. When you call That's different than Understanding the difference between |
The Law of Leaky Abstractions |
@really i don't see why we can fire events from the builder, since we have all the necessary functionality. For now I have extended the builder class, added this function
Then add the proper $this->fireModelEvent('deleted', false) , and $this->fireModelEvent('save', false) Let me know what you think |
+1 for solving this issue. Details where I found this useful. Why it isn't working is logical, but not obvious. At least this should be documented in Query builder section. |
Btw in 2018 you can replace with |
Thank you.. It works.. !! made my day.. !! :) |
For those who wonder how it works, |
Wouldn't it be possible for |
To be more accurate, you can use higher order functions in versions >= 5.4 https://laravel.com/docs/5.4/collections#higher-order-messages |
On what circumstances will |
@chrisadipascual whenever you call the |
@beasty-web Thanks for the response! Should have tried deleting a single model before asking. I was tinkering with a whereIn query. The each workaround @arvins-wittymanager described works beautifully! |
@chrisadipascual he actually quoted me with his response 😄 But be aware that the performance will be significantly worse with the |
@orrd Many Many Thanks For your description . |
In case there are thousands of items to delete, the |
@nightwalkeryao Yes, first that will load all of the models into memory, and then call delete on each one ( |
You guys should read this comment on SO. It's really solved the problem. |
That's a solution for a different problem. For example, the "scenario A" in the original question on this issue would also not trigger that deleting event handler in the SO answer that you linked to. This issue was about someone noticing that certain types of delete code won't trigger delete events on the models. |
Really old thread but I managed to make this misstake today. |
or you can fetch the models and call delete on the model rather than the query builder replace |
Scenario A
Analytic::where('id', 2)->delete();
Scenario B
Analytic::where('id', 2)->first()->delete();
Is this expected behavior?
referring doc: http://four.laravel.com/docs/eloquent
The text was updated successfully, but these errors were encountered: