0

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

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

没有软删除的模型: 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只会调用softdeletiondestroy。

更新

我通过检查是否在模型“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

我仍然非常想知道是否有任何方法可以在方法堆栈的上方调用 super .. 任何人?

4

1 回答 1

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
于 2013-06-29T11:03:58.603 回答