如何对单个 ActiveModel/ActiveRecord 对象进行验证?

Joh*_*lla 5 validation activerecord ruby-on-rails activemodel

你有一个模型,比如说,Car。一些验证Car始终适用于每个实例:

class Car
  include ActiveModel::Model

  validates :engine, :presence => true
  validates :vin,    :presence => true
end
Run Code Online (Sandbox Code Playgroud)

但是一些验证只在特定的上下文中相关,所以只有某些实例应该有它们。您想在某处执行此操作:

c = Car.new
c.extend HasWinterTires
c.valid?
Run Code Online (Sandbox Code Playgroud)

这些验证放在别处,进入不同的模块:

module HasWinterTires
  # Can't go fast with winter tires.
  validates :speed, :inclusion => { :in => 0..30 }
end
Run Code Online (Sandbox Code Playgroud)

如果你这样做,validates将会失败,因为它没有在Module. 如果添加include ActiveModel::Validations,那也不起作用,因为它需要包含在类中。

在不向原始类中塞入更多内容的情况下对模型实例进行验证的正确方法是什么?

CDu*_*Dub 0

Car您可以对Car extends模块执行验证HasWinterTires...例如:

class Car < ActiveRecord::Base

  ...

  validates :speed, :inclusion => { :in => 0..30 }, :if => lambda { self.singleton_class.ancestors.includes?(HasWinterTires) }

end
Run Code Online (Sandbox Code Playgroud)

我认为你可以代替self.is_a?(HasWinterTires)singleton_class.ancestors.include?(HasWinterTires)但我还没有测试过。