I've got a record in my Rails app with an after_destroy
hook that needs to do be aware why the record gets destroyed. More specifically, if the record is being destroyed in a cascade because its parent says dependent: :destroy
, it needs to do things differently than if the record was individually destroyed.
What I tried to do is to see if its parent was destroyed?
, only to figure out that dependent: :destroy
callbacks are done before the parent is destroyed. Which makes sense because it should be able to fail. (i.e. restrict).
So, how do I do this?
Solution #1
If your model is simple enough and you don't need to invoke any callbacks in the child relation, you can just use
dependent: delete_all
in the parent.Solution #2
For more complex scenarios you can use
destroyed_by_association
, which returns aActiveRecord::Reflection::HasManyReflection
object when it's part of cascade, or nil otherwise:I just tried this in Rails 4.2 and it works.
Source: https://github.com/rails/rails/issues/12828#issuecomment-28142658
One way to do this is using the
before_destroy
callback in the parent object to mark all child objects as destroyed through parent destroy. Like his:You can also use ActiveRecord Reflections to determine automaticly which associations are marked as
:dependent => :destroy
. Doing this is helpfull when you need this function in many classes.