跳至内容 跳至搜索

Active Model 验证

为您的对象提供完整的验证框架。

一个最小的实现可能是

class Person
  include ActiveModel::Validations

  attr_accessor :first_name, :last_name

  validates_each :first_name, :last_name do |record, attr, value|
    record.errors.add attr, "starts with z." if value.start_with?("z")
  end
end

它为您提供了您从 Active Record 中了解的完整的标准验证堆栈。

person = Person.new
person.valid?                   # => true
person.invalid?                 # => false

person.first_name = 'zoolander'
person.valid?                   # => false
person.invalid?                 # => true
person.errors.messages          # => {first_name:["starts with z."]}

请注意,ActiveModel::Validations 会自动为您的实例添加一个 errors 方法,该方法用一个新的 ActiveModel::Errors 对象初始化,因此您无需手动执行此操作。

命名空间
方法
E
F
I
R
V
包含的模块

实例公共方法

errors()

返回保存所有关于属性错误消息信息的 Errors 对象。

class Person
  include ActiveModel::Validations

  attr_accessor :name
  validates_presence_of :name
end

person = Person.new
person.valid? # => false
person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
# File activemodel/lib/active_model/validations.rb, line 328
def errors
  @errors ||= Errors.new(self)
end

freeze()

# File activemodel/lib/active_model/validations.rb, line 372
def freeze
  errors
  context_for_validation

  super
end

invalid?(context = nil)

执行与 valid? 相反的操作。如果添加了错误,则返回 true,否则返回 false

class Person
  include ActiveModel::Validations

  attr_accessor :name
  validates_presence_of :name
end

person = Person.new
person.name = ''
person.invalid? # => true
person.name = 'david'
person.invalid? # => false

可以选择提供上下文以定义要测试的回调(上下文在使用 :on 对验证进行定义时定义)。

class Person
  include ActiveModel::Validations

  attr_accessor :name
  validates_presence_of :name, on: :new
end

person = Person.new
person.invalid?       # => false
person.invalid?(:new) # => true
# File activemodel/lib/active_model/validations.rb, line 408
def invalid?(context = nil)
  !valid?(context)
end

valid?(context = nil)

运行所有指定的验证,如果未添加任何错误,则返回 true,否则返回 false

class Person
  include ActiveModel::Validations

  attr_accessor :name
  validates_presence_of :name
end

person = Person.new
person.name = ''
person.valid? # => false
person.name = 'david'
person.valid? # => true

可以选择提供上下文以定义要测试的回调(上下文在使用 :on 对验证进行定义时定义)。

class Person
  include ActiveModel::Validations

  attr_accessor :name
  validates_presence_of :name, on: :new
end

person = Person.new
person.valid?       # => true
person.valid?(:new) # => false
也称为:validate
# File activemodel/lib/active_model/validations.rb, line 361
def valid?(context = nil)
  current_context = validation_context
  context_for_validation.context = context
  errors.clear
  run_validations!
ensure
  context_for_validation.context = current_context
end

validate(context = nil)

别名:valid?

validate!(context = nil)

在指定上下文中运行所有验证。如果未找到任何错误,则返回 true,否则引发 ValidationError

Validations 没有 :on 选项,无论上下文如何,都会运行。 Validations 有一些 :on 选项,将仅在指定的上下文中运行。

# File activemodel/lib/active_model/validations.rb, line 417
def validate!(context = nil)
  valid?(context) || raise_validation_error
end

validates_with(*args, &block)

将记录传递给指定的类或类,并允许它们根据更复杂的条件添加错误。

class Person
  include ActiveModel::Validations

  validate :instance_validations

  def instance_validations
    validates_with MyValidator
  end
end

请参阅类方法文档以获取有关创建您自己的验证器的更多信息。

您也可以传递多个类,如下所示

class Person
  include ActiveModel::Validations

  validate :instance_validations, on: :create

  def instance_validations
    validates_with MyValidator, MyOtherValidator
  end
end

标准配置选项(:on:if:unless)在类的 validates_with 版本中可用,应放在 validates 方法上,因为这些选项将在回调中应用和测试。

如果您传递任何其他配置选项,它们将传递给类并可用作 options,请参阅此方法的类版本以获取更多信息。

# File activemodel/lib/active_model/validations/with.rb, line 144
def validates_with(*args, &block)
  options = args.extract_options!
  options[:class] = self.class

  args.each do |klass|
    validator = klass.new(options.dup, &block)
    validator.validate(self)
  end
end

validation_context()

返回运行验证时的上下文。

当运行验证除某个上下文之外的验证时(与 on 选项相反),这很有用。

class Person
  include ActiveModel::Validations

  attr_accessor :name
  validates :name, presence: true, if: -> { validation_context != :custom }
end

person = Person.new
person.valid?          #=> false
person.valid?(:new)    #=> false
person.valid?(:custom) #=> true
# File activemodel/lib/active_model/validations.rb, line 454
def validation_context
  context_for_validation.context
end

实例私有方法

raise_validation_error()

# File activemodel/lib/active_model/validations.rb, line 478
def raise_validation_error # :doc:
  raise(ValidationError.new(self))
end