跳至内容 跳至搜索

Active Model 验证器

一个简单的基类,可以与 ActiveModel::Validations::ClassMethods.validates_with 一起使用。

class Person
  include ActiveModel::Validations
  validates_with MyValidator
end

class MyValidator < ActiveModel::Validator
  def validate(record)
    if some_complex_logic
      record.errors.add(:base, "This record is invalid")
    end
  end

  private
    def some_complex_logic
      # ...
    end
end

任何继承自 ActiveModel::Validator 的类都必须实现一个名为 validate 的方法,该方法接受一个 record 参数。

class Person
  include ActiveModel::Validations
  validates_with MyValidator
end

class MyValidator < ActiveModel::Validator
  def validate(record)
    record # => The person instance being validated
    options # => Any non-standard options passed to validates_with
  end
end

要引发验证错误,必须直接从验证器的消息中将错误添加到 record 的 errors 中。

class MyValidator < ActiveModel::Validator
  def validate(record)
    record.errors.add :base, "This is some custom error message"
    record.errors.add :first_name, "This is some complex validation"
    # etc...
  end
end

要在 initialize 方法中添加行为,请使用以下签名:

class MyValidator < ActiveModel::Validator
  def initialize(options)
    super
    @my_custom_field = options[:field_name] || :first_name
  end
end

请注意,验证器仅在整个应用程序生命周期内初始化一次,而不是在每次验证运行时初始化。

为单个属性添加自定义验证器的最简单方法是使用方便的 ActiveModel::EachValidator 类。

class TitleValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
  end
end

现在可以将其与 validates 方法结合使用。有关更多信息,请参阅 ActiveModel::Validations::ClassMethods#validates

class Person
  include ActiveModel::Validations
  attr_accessor :title

  validates :title, presence: true, title: true
end

当存在诸如 attr_accessor 是否存在的先决条件时,访问使用该验证器的类会很有用。该类可通过构造函数中的 options[:class] 访问。要设置您的验证器,请覆盖构造函数。

class MyValidator < ActiveModel::Validator
  def initialize(options={})
    super
    options[:class].attr_accessor :custom_attribute
  end
end
方法
K
N
V

Attributes

[R] options

类公共方法

kind()

返回验证器的种类。

PresenceValidator.kind   # => :presence
AcceptanceValidator.kind # => :acceptance
# File activemodel/lib/active_model/validator.rb, line 103
def self.kind
  @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
end

new(options = {})

接受将通过 options 读取器提供的选项。

# File activemodel/lib/active_model/validator.rb, line 108
def initialize(options = {})
  @options = options.except(:class).freeze
end

实例公共方法

kind()

返回此验证器的种类。

PresenceValidator.new(attributes: [:username]).kind # => :presence
AcceptanceValidator.new(attributes: [:terms]).kind  # => :acceptance
# File activemodel/lib/active_model/validator.rb, line 116
def kind
  self.class.kind
end

validate(record)

在子类中覆盖此方法以进行验证逻辑,并在必要时将错误添加到记录的 errors 数组中。

# File activemodel/lib/active_model/validator.rb, line 122
def validate(record)
  raise NotImplementedError, "Subclasses must implement a validate(record) method."
end