绑定到原始的activerecord方法

时间:2013-06-29 09:16:43

标签: ruby-on-rails ruby activerecord bind

我正在为我的多个模型实现一个简单的软删除功能。我正在使用rails问题,所以我将逻辑保存在一个地方(如果担心的是最好的方法不是这里的问题)

基本上,destroy方法的调用顺序是:

没有softdeletion的模型: 1. ActiveRecord :: Base.destroy

具有软删除的模型: 1. SoftDeletion.destroy 2. ActiveRecord :: Base.destroy

现在我的问题! 在某些模型中,我需要覆盖destroy方法,以便能够在模型具有特定状态时进行硬删除(基本上让一些逻辑确定应该只是软删除还是完全删除)。它的工作原理如下:

def destroy
     if someValue
         # call original destroy
     else
         # call soft deletion
     end
end

考虑到方法调用顺序,我如何获得原始的ActiveRecord :: Base.destroy? 在重写的destroy中调用super只会调用softdeletion destroy。

更新

我通过检查是否在模型“soft_delete_when”上声明了另一个方法来解决问题,并检查该方法是否返回true。

module SoftDeletion
    extend ActiveSupport::Concern

    included do
        scope :active, where("deleted_at is null")
        scope :deleted, where("deleted_at is not null")
    end

    def destroy
        if self.class.instance_methods(false).include? :soft_delete_when
            unless self.soft_delete_when
                super
            else
                touch(:deleted_at)
            end
        else
            touch(:deleted_at)
        end
    end

    def is_destroyed?
        deleted_at != nil
    end

    def undestroy
        update_attribute(:deleted_at, nil)
    end

end

我仍然非常想知道是否有任何方法可以进一步调用方法堆栈..任何人?

1 个答案:

答案 0 :(得分:0)

如何使用alias_method_chain

module SoftDeletion
  def self.included(base)
    base.class_eval do
      alias_method_chain :destroy, :soft_delete
    end
  end
  # (...)

  def destroy_with_soft_delete
    if self.class.instance_methods(false).include? :soft_delete_when
      unless self.soft_delete_when
        destroy_without_soft_delete
      else
        touch(:deleted_at)
      end
    else
      touch(:deleted_at)
    end
  end
  # (...)
end

并在您的ActiveRecord班级中:

def destroy
  if someValue
    destroy_without_soft_delete
  else
    destroy_with_soft_delete
  end
end