-
Notifications
You must be signed in to change notification settings - Fork 21.7k
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
dependent => :destroy deletes children before "before_destroy" is executed #3458
Comments
Per discussion on #670, the problem is that |
me too facing the same problem..... |
hey it is not a issue in rails... since previously we are doing everything in transaction for dependent destroy, but now in Rails 3.1.3 we are building the before_destroy method internally we need to rearrange the code. so your code should be: class Foo < AR::Base def check class Child < AR::Base class Grandchild < AR::Base This will do the trick..... :) |
Good one @mitijain123 |
@mitjain123: I respectfully disagree.. I think macros should try as hard as possible to act as declarative as they look. |
@jaylevitt did you tried this? here is the rails code which does that. def configure_dependency if options[:dependent] unless options[:dependent].in?([:destroy, :delete_all, :nullify, :restrict]) raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, " \ ":nullify or :restrict (#{options[:dependent].inspect})" end send("define_#{options[:dependent]}_dependency_method") model.before_destroy dependency_method_name end end so this is creating a method: before_destroy :X_method and if X_method is defined before any other before_destroy that will be executed. may this makes you more clear. |
@mitjain123: I'm saying class macros like |
the workaround, to move the before_destroy callback before the has_many, actually only works half way!! |
Maybe at least make this behaviour clear in the documentation? |
This is a regression as |
Is this still an issue? |
@isaacsanders: yes. |
Just want to chime in that I got bitten by this. Can't they be moved to a different chain that's executed after user-defined |
Just bitten by this too. +1 to a less error-prone solution for this issue, independent of the macro definition order. |
@pyrat are you sure it was working in 3.0.10? I just did a test and it's broken there too. |
Just bitten by this too in Rails 3.2.3 +1 For a better solution, or at least indicate this in documentation. |
Just bit me too. I agree that this should, at least, be in the documentation. |
Same problem here with 3.2.2. Is there any workaround for observers? |
We have also ran into this issue. If this is expected behaviour then it should be clearly highlighted in the documentation. |
I've just pushed lifo/docrails#ecaf72877, which adds documentation for this behavior. Changing this behavior might mess with existing apps, and so we'd need a migration path. Since it's not exactly a bug, and I've written documentation, I'm giving this a close. If someone would like to make them work in a more declarative fashion, please implement it and submit a pull request, or ping rails-core to see if it's even a good idea; changing this may subtly break a lot of apps. Thanks! |
Just got bitten by this too. It is definitely counter intuitive, especially if your models are defined in an acts_as module and you want your code to look like class MyClass
acts_as_foo
before_destroy :bar
end @steveklabnik Seeing as how it subtly broke a lot of apps by changing to the way it is right now, I think "how do you think it should work" should be the criteria for deciding on the behaviour. I'll poke around in there and see if there's a way to do it that makes sense, and doesn't require us to document why this doesn't work the way you expect it to work anymore. |
Biten by this too. I agree with @jaylevitt, this is a bug and not a "documentation problem". Declarations orders shouldn't matter. |
@steveklabnik I feel like this should also be mentioned in the documentation for Right now, I don't think there is any way for |
Go ahead and send a pull request to rails/rails-observers , since Observers are no longer in Rails. |
Moving before_destroy callbacks because of rails/rails#3458
(cherry picked from commit 5630b13)
Moving before_destroy callbacks because of rails/rails#3458
…icked from commit 5630b13)
Just bitten by this too. This should be mentioned in the documentation at least. Very frustrating! |
…Product/Variant Previously : ensure_no_line_items callback could stop deleting the Product/Variant but associations (with dependent: :destroy) were deleted whatsoever, as this is a rails bug (see rails/rails#3458)
…Product/Variant Previously : ensure_no_line_items callback could stop deleting the Product/Variant but associations (with dependent: :destroy) were deleted whatsoever, as this is a rails bug (see rails/rails#3458)
…Product/Variant Previously : ensure_no_line_items callback could stop deleting the Product/Variant but associations (with dependent: :destroy) were deleted whatsoever, as this is a rails bug (see rails/rails#3458)
…Country Previously :ensure_not_default callback could stop deleting the Country but associations (with dependent: :destroy) were deleted whatsoever, as this is a rails bug (see rails/rails#3458)
Is this still an issue? |
Same |
1 similar comment
Same |
Still having the same issue here too |
Yeah, I just fixed it by swapping positions for |
Another approach (basically built for this): (using the original example)
Reference: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html |
@xinranxiao Here if you want to restrict to delete record need to throw exception to abort |
^that is only the case if using Rails 5 with |
i solved this problem by using a funny hack, |
I just got bit too, but by |
Reposting #670 since the lighthouse importer auto-closed it, even though it was still open on lighthouse...
Problem: Upon destroying an ActiveRecord::Base object, the "before_destroy" method - which should trigger a transaction rollback if returning false - is only exceuted AFTER all child objects have been destroyed via ":dependent => :destroy".
However, this prevents
before_destroy
from seeing those same child objects, in case it needs them to determine whether the destruction should be successful.Expected behaviour:
before_destroy
should be called before any objects are destroyed, even child records. Thebefore_destroy
context should see the original state of the application as ifdestroy
were never called. It should be executed within thedestroy
transaction, however, so that any changes it makes can be rolled back.The text was updated successfully, but these errors were encountered: