有条件地覆盖 ActiveRecord 的删除机制的最佳方法是什么?
What's the best way to conditionally override ActiveRecord's deletion mechanism?
我正在尝试劫持 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
是一种每次returns不同对象的方法...
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
...但这会导致其他模型上的堆栈溢出。
帮忙?
覆盖模型上的 delete
和 destroy
应该可以完成您想要的大部分内容。查看 Paranoia gem 是如何完成覆盖的。该库只有 200 行左右,并且还处理关联模型(例如,当您有 dependent: :destroy
)时。
我正在尝试劫持 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
是一种每次returns不同对象的方法...
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
...但这会导致其他模型上的堆栈溢出。
帮忙?
覆盖模型上的 delete
和 destroy
应该可以完成您想要的大部分内容。查看 Paranoia gem 是如何完成覆盖的。该库只有 200 行左右,并且还处理关联模型(例如,当您有 dependent: :destroy
)时。