views:

135

answers:

1

I am writing a plugin that provides drafting for models. A delete action is a draftable action and I do not always want to delete the origin until that deletion is published. So I wrote my own destroy method to help out with this. Everything works exactly as I want things to except, custom callbacks for :before_destroy and :after_destroy are no longer being triggered.

Any ideas on how to:

  1. rebind callbacks to my destroy method
  2. works some alias_method_chain voodoo
  3. get a list of model callbacks so I can call them manual
  4. solve this problem another way

Here is my destroy method:

  def destroy
    if self.attribute_names.include?('draft') && self.skip_draft == false
      if handle_destroy # if true is returned
        super # go ahead and destroy as normal
      end
    else
      super
    end
  end

Update: I just found this: correct way to override activerecordbasedestroy, but that seems like the proposed technique does not accomodate for callbacks either. Is there a way to have my cake and eat it too?

A: 

I was wrong about the callbacks not being called when super is called. I ended up relying on the exact code I initially posted. I changed how my handle_destroy method returned

I'll show you how I figured out how it is possible to fire the callbacks in the event you want to explicitly fire the callbacks.

  def destroy
    if self.attribute_names.include?('draft') && self.skip_draft == false
      if handle_destroy # if true is returned
        super # go ahead and destroy as normal
      else
        # Execute all custom callbacks that are not dependent type callbacks (ie: if the callback method name contains "dependent")
        #   Dependent callbacks delete records and this is not what the drafting system is all about.
        (self.class.before_destroy_callback_chain + self.class.after_destroy_callback_chain).each do |cb|
          unless (cb.method.kind_of?(Symbol) && cb.method.to_s.match(/dependent/))
            cb.call(self)
          end
        end
      end
    else
      # normal delete
      super
    end
  end
Sean McCleary