Rails ActiveSupport:如果模型没有响应,是否会在包含时引发异常?一些方法

问题描述

我正在编写一个添加到多个模型的 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

然而,这个异常总是被引发。

  • 关注点通常(由于样式指南)包含在模型的顶部;但是,此时我们还没有到达模型中的 def 调用,因此尚未定义实例方法

  • 即使我们在模型的最底部包含关注点(为了更好的开发者体验,我真的希望我可以避免这种情况),我注意到如果 some_instance_method 实际上是一个列名,如果我事先实例化模型,它只会响应 truemethod_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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...