I have the following model:
class PhoneNumber < ActiveRecord::Base
has_many :personal_phone_numbers, :dependent => :destroy
has_many :people, :through => :personal_phone_numbers
end
I want to set up an observer to run an action in a delayed_job queue, which works for the most part, but with one exception. I want the before_destroy watcher to grab the people associated with the phone number, before it is destroyed, and it is on those people that the delayed job actually works.
The problem is, when a phone number is destroyed, it destroys the :personal_phone_numbers
record first, and then triggers the observer when it attempts to destroy the phone number. At that point, it's too late.
Is there any way to observe the destroy action before dependent records are deleted?
While this isn't ideal, you could remove the
:dependent => :destroy
from thepersonal_phone_numbers
relationship, and delete them manually in the observer after operating on them.However, I think that this issue might be showing you a code smell. Why are you operating on people in an observer on phone number. It sounds like that logic is better handled in the join model.
Use alias_method to intercept the destroy call?
You can use a before_destroy callback in the model, then grab the data and do whatever operation you need to before destroy the parent. Something like this example should be what you are looking for:
It sounds like your problem in a nutshell is that you want to gather and act on a collection of
Person
when aPersonalPhoneNumber
is destroyed. This approach may fit the bill!Here is an example of a custom callback to collect
Person
models. Here it's an instance method so we don't have to instantiate aPersonalPhoneNumberCallbacks
object in the ActiveRecord model.Next, add the callback do your ActiveRecord model:
Your
after_destroy
callback will have the model passed down and you can act on its data. After the callback chain is complete, it will be destroyed.References