ActiveModel ::匿名类的验证

mot*_*tns 13 ruby activemodel

我正在开发一个类似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
Run Code Online (Sandbox Code Playgroud)

只有在验证程序失败时才会引发异常 - 我猜测在尝试构造验证错误消息时会发生问题.所以我的问题是:

  • 我做了很多搜索,但找不到任何人试图做类似的事情.这是不可能使用ActiveModel,还是有一个我不知道的解决方法?

Jim*_*lle 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
Run Code Online (Sandbox Code Playgroud)


hji*_*ing 10

ActiveModel::Name 这里的初始化函数抛出了错误.

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
Run Code Online (Sandbox Code Playgroud)

因此,而不是定义一个类的方法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
Run Code Online (Sandbox Code Playgroud)