跳至内容 跳至搜索

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
I
R
V
包含的模块

属性

[RW] 验证上下文

实例公共方法

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

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 402
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, self.validation_context = validation_context, context
  errors.clear
  run_validations!
ensure
  self.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 411
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 49
      

实例私有方法

raise_validation_error()

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