In rails, how to determine if an entry was destroyed by the dependent :: destroy callback?

I have an entry in my Rails application with an after_destroy hook that needs to know why the entry is destroyed. More specifically, if a record is destroyed in a cascade because its parent says dependent: :destroy , it must do something different than if the record was individually destroyed.

I tried to find out if his parent was destroyed? , only to find out that the dependent: :destroy callbacks are executed before the parent is destroyed. This makes sense because he should be able to fail. (i.e. limit).

So how do I do this?

+8
callback ruby-on-rails activerecord
source share
2 answers

Decision No. 1

If your model is simple enough and you don't need to refer to any callbacks in a child relation, you can just use dependent: delete_all in the parent.

Decision number 2

For more complex scenarios, you can use destroyed_by_association , which returns an ActiveRecord::Reflection::HasManyReflection when it is part of a cascade, or else:

 after_destroy :your_callback def your_callback if destroyed_by_association # this is part of a cascade else # isolated deletion end end 

I just tried this in Rails 4.2 and it works.

Source: https://github.com/rails/rails/issues/12828#issuecomment-28142658

+4
source share

One way to do this is to use the before_destroy in the parent object to mark all child objects destroyed by parent destruction. Like him:

 class YourClass before_destroy :mark_children ... ... def mark_children [:association1, :association2].each do |association| # Array should inclue association names that hate :dependent => :destroy option self.send(association).each do |child| # mark child object as deleted by parent end end end end 

You can also use ActiveRecord Reflections to automatically determine which associations are marked as :dependent => :destroy . This is useful when you need this feature in many classes.

+3
source share

All Articles