14

我正在开发一个类似于 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

仅当验证器失败时才会引发异常 - 我猜当它尝试构造验证错误消息时会发生问题。所以我的问题是:

  • 我做了很多搜索,但找不到任何人试图做类似的事情。这对 ActiveModel 来说是不可能的,还是有我不知道的解决方法?
4

2 回答 2

21

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
于 2013-01-21T02:57:38.873 回答
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

因此,您可以定义一个返回 a的类方法,而不是定义一个model_name返回 的类方法。ActiveModel::NamenameString

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
于 2014-10-02T19:39:13.550 回答