我正在开发一个类似DataMapper的小型ODM项目,我正在尝试使用ActiveModel::Validations
组件。但是,我在编写测试时遇到了问题 - 我正在使用匿名类来构建我的测试模式,但是当运行验证器时,ActiveModel::Name
类会抛出错误:
Class name cannot be blank. You need to supply a name argument when anonymous class given
这是一个重现的简单代码示例:
require 'active_model'
book_class = Class.new do
include ActiveModel::Validations
validates_presence_of :title
def title; ""; end # This will fail validation
end
book_class.new.valid? # => throws error
只有在验证程序失败时才会引发异常 - 我猜测在尝试构造验证错误消息时会发生问题。所以我的问题是:
答案 0 :(得分:17)
ActiveModel在设置错误消息时尝试获取模型名称(如此处所示)。绕过它的最快方法(不给匿名类命名)是为您的类提供一个返回model_name
实例的类方法ActiveModel::Name
。
例如
require 'active_model'
book_class = Class.new do
include ActiveModel::Validations
def self.model_name
ActiveModel::Name.new(self, nil, "temp")
end
validates_presence_of :title
def title; ""; end # This will fail validation
end
book_class.new.valid? # => no error
答案 1 :(得分:10)
ActiveModel::Name
here的初始化函数中抛出了错误。
module ActiveModel
class Name
def initialize(klass, namespace = nil, name = nil)
@name = name || klass.name
raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?
# ...
end
end
end
因此,您可以定义返回model_name
的类方法ActiveModel::Name
,而不是定义返回name
的类方法String
。
require 'active_model'
book_class = Class.new do
include ActiveModel::Validations
validates_presence_of :title
def self.name
"Book"
end
def title; ""; end # This will fail validation
end
book_class.new.valid? # => false