我正在尝试将Ruby 1.9.3应用程序升级到2.0,除了一次打嗝之外,一切似乎都很顺利。我写了一个模块,我在模型中包含了覆盖activerecord destroy的模块。它将现有destroy
方法别名为destroy!
,然后覆盖destroy
以更改记录上的deleted_at
时间戳。只有当我升级到ruby 2.0 destroy!
时才会破坏记录,但行为就像我的新覆盖方法一样。知道为什么会这样吗?代码的相关部分如下。完整的要点here。
def self.included(base)
base.class_eval do
alias_method :destroy!, :destroy
alias_method :delete!, :delete
default_scope -> { where(:deleted_at => nil) }
end
base.send :extend, ClassMethods
base.send :include, InstanceMethods
end
答案 0 :(得分:1)
查看paranoia gem。这是一个Rails 3/4兼容的软删除实现,可以完成你所追求的目标。如果您只想提供软删除,那么我将使用gem并完成它。如果你希望自己实现软删除,那么实现可以为你提供一些关于它之前是如何完成的见解。
答案 1 :(得分:0)
如果您为当前类中未直接定义的方法添加别名,则alias
会在执行该类的类的最近祖先中查找该方法。
当您将Trashable::InstanceMethods
包含在其中一个模型中时,它会插入该模型的祖先链的前面。因此,在该模型中调用destroy!
会触发destroy
上的Trashable::InstanceMethods
方法。
如果您将def destroy
从InstanceMethods
移到base.class_eval
,那么它将直接在包含模型中定义,并且包含'destroy'的该模型的最近祖先将是ActiveRecord中的相关模块。因此,调用destroy!
会按预期触发SQL DELETE
。
请参阅class.ancestors
以进一步探讨此行为。
答案 2 :(得分:0)
在Ruby 2.0中,他们引入了预先添加模块的概念,因此您可以在模型和ActiveRecord :: Base之间插入行为。我建议将代码移动到模块中,而不是包含该模型,您可以将其添加到模块中。从别名方法中保存。
以下是一些与新前置功能相关的文章:
https://gist.github.com/mattetti/5104790
http://blog.crowdint.com/2012/11/05/3-killer-features-that-are-coming-on-ruby-2-0.html