问题描述
我正在编写一个将添加到多个模型的 Rails 关注点。为了更加安全,我想确保包含此问题的所有模型都响应某些实例方法。如果你愿意,可以称之为合同。
无论如何,这是我希望工作的代码:
module SomeConcern
extend ActiveSupport::Concern
included do
raise("The model has to respond to some_instance_method") if !self.method_defined?(:some_instance_method)
end
end
然而,这个异常总是被引发。
-
即使我们在模型的最底部包含关注点(为了更好的开发者体验,我真的希望我可以避免这种情况),我注意到如果
some_instance_method
实际上是一个列名,如果我事先实例化模型,它只会响应true
到method_defined?
。
在 binding.pry
块内使用 included
,会发生这种情况:
self.method_defined?(:some_column_name)
=> false
self.new
self.method_defined?(:some_column_name)
=> true
那么,考虑到所有这些,当关注点包含在模型中时,引发异常的最佳方法是什么,以确保该模型的一个实例实际上响应了我想要检查的某些方法?
解决方法
您可以在 some_instance_method
中定义一个默认的 SomeConcern
,如果您在 raise
中没有同名的方法,则在调用它时会出现 SomeModal
错误:
module SomeConcern
extend ActiveSupport::Concern
def some_instance_method
raise("The model has to respond to some_instance_method")
end
end
class SomeModal
include SomeConcern
def some_instance_method
do_the_work
end
end