有条件地覆盖ActiveRecord删除机制的最佳方法是什么?

时间:2015-06-03 22:45:33

标签: ruby-on-rails activerecord override

我正试图劫持Rails'删除机制,使其对某组模型的行为不同。

ActiveRecord::Base#delete#destroy都会返回ActiveRecord::Relation#delete_all,因此覆盖此方法是有意义的。

我试过......

class MyModel < ActiveRecord::Base
  class << all
    def delete_all
      "My destruction mechanism"
    end
  end
end

...但::all是一种每次都返回不同对象的方法......

class MyModel < ActiveRecord::Base
  def self.all
    super.tap do |obj|
      class << obj
        def delete_all
          "My destruction mechanism"
        end
      end
    end
  end
end

...但::all不是唯一的范围,无论如何都需要覆盖它......

class ActiveRecord::Relation
  def delete_all(*args)
    "My destruction mechanism"
  end
end

...但可以应用于MyModel及其子类......

class ActiveRecord::Relation
  def delete_all(*args)
    if @klass.new.is_a?(MyModel)
      "My destruction mechanism"
    else
      super
    end
  end
end

...但这会导致其他型号的堆栈溢出。

帮助?

1 个答案:

答案 0 :(得分:1)

覆盖模型上的deletedestroy应该可以完成您想要的大部分工作。看看Paranoia宝石如何完成它的覆盖。图书馆只有200行左右,并且还处理相关模型(例如,当你有dependent: :destroy时)。