跳至内容 跳至搜索

Active Model Validations

提供了一套完整的验证框架给您的对象。

一个最小化的实现可以是

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 330
def errors
  @errors ||= Errors.new(self)
end

freeze()

# File activemodel/lib/active_model/validations.rb, line 374
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 410
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 363
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

没有 :on 选项的 Validations 将无论上下文如何运行。具有 :on 选项的 Validations 只会在指定上下文中运行。

# File activemodel/lib/active_model/validations.rb, line 419
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()

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

# File activemodel/lib/active_model/validations.rb, line 442
def validation_context
  context_for_validation.context
end

实例私有方法

raise_validation_error()

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