Active Model 错误
提供错误相关功能,可以包含在对象中,用于处理错误消息并与 Action View 帮助器交互。
最简单的实现可能是
class Person
# Required dependency for ActiveModel::Errors
extend ActiveModel::Naming
def initialize
@errors = ActiveModel::Errors.new(self)
end
attr_accessor :name
attr_reader :errors
def validate!
errors.add(:name, :blank, message: "cannot be nil") if name.nil?
end
# The following methods are needed to be minimally implemented
def read_attribute_for_validation(attr)
send(attr)
end
def self.human_attribute_name(attr, options = {})
attr
end
def self.lookup_ancestors
[self]
end
end
对象中需要最后三个方法,以便 `Errors` 能够正确生成错误消息,并且还可以处理多种语言。当然,如果使用 ActiveModel::Translation
扩展对象,则不需要实现最后两个方法。同样,使用 ActiveModel::Validations
将处理与验证相关的对象方法。
上述内容允许你执行
person = Person.new
person.validate! # => ["cannot be nil"]
person.errors.full_messages # => ["name cannot be nil"]
# etc..
- #
- A
- C
- D
- E
- F
- G
- H
- I
- K
- M
- N
- O
- S
- T
- W
属性
[R] | errors |
|
[R] | objects |
|
类公共方法
new(base) 链接
传入使用错误对象的实例。
class Person
def initialize
@errors = ActiveModel::Errors.new(self)
end
end
来源: 显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 117 def initialize(base) @base = base @errors = [] end
实例公共方法
[](属性) 链接
当传递一个符号或一个方法名称时,返回该方法的错误数组。
person.errors[:name] # => ["cannot be nil"]
person.errors['name'] # => ["cannot be nil"]
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 229 def [](attribute) messages_for(attribute) end
add(属性,类型 = :invalid,**选项) 链接
在属性
上添加一个新的类型
错误。可以向同一个属性
添加多个错误。如果没有提供类型
,则假定为:invalid
。
person.errors.add(:name)
# Adds <#ActiveModel::Error attribute=name, type=invalid>
person.errors.add(:name, :not_implemented, message: "must be implemented")
# Adds <#ActiveModel::Error attribute=name, type=not_implemented,
options={:message=>"must be implemented"}>
person.errors.messages
# => {:name=>["is invalid", "must be implemented"]}
如果类型
是一个字符串,它将被用作错误消息。
如果类型
是一个符号,它将使用适当的范围进行翻译(参见generate_message
)。
person.errors.add(:name, :blank)
person.errors.messages
# => {:name=>["can't be blank"]}
person.errors.add(:name, :too_long, count: 25)
person.errors.messages
# => ["is too long (maximum is 25 characters)"]
如果类型
是一个过程,它将被调用,允许在错误中使用诸如Time.now
之类的东西。
如果:strict
选项设置为true
,它将引发ActiveModel::StrictValidationFailed
而不是添加错误。:strict
选项也可以设置为任何其他异常。
person.errors.add(:name, :invalid, strict: true)
# => ActiveModel::StrictValidationFailed: Name is invalid
person.errors.add(:name, :invalid, strict: NameIsInvalid)
# => NameIsInvalid: Name is invalid
person.errors.messages # => {}
如果错误与单个属性没有直接关联,则应将属性
设置为:base
。
person.errors.add(:base, :name_or_email_blank,
message: "either name or email must be present")
person.errors.messages
# => {:base=>["either name or email must be present"]}
person.errors.details
# => {:base=>[{error: :name_or_email_blank}]}
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 342 def add(attribute, type = :invalid, **options) attribute, type, options = normalize_arguments(attribute, type, **options) error = Error.new(@base, attribute, type, **options) if exception = options[:strict] exception = ActiveModel::StrictValidationFailed if exception == true raise exception, error.full_message end @errors.append(error) error end
added?(属性,类型 = :invalid,选项 = {}) 链接
如果错误与提供的属性
和类型
匹配,则返回true
,否则返回false
。类型
的处理方式与add
相同。
person.errors.add :name, :blank
person.errors.added? :name, :blank # => true
person.errors.added? :name, "can't be blank" # => true
如果错误需要选项,则它将返回带有正确选项的true
,或返回带有不正确或缺失选项的false
。
person.errors.add :name, :too_long, count: 25
person.errors.added? :name, :too_long, count: 25 # => true
person.errors.added? :name, "is too long (maximum is 25 characters)" # => true
person.errors.added? :name, :too_long, count: 24 # => false
person.errors.added? :name, :too_long # => false
person.errors.added? :name, "is too long" # => false
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 372 def added?(attribute, type = :invalid, options = {}) attribute, type, options = normalize_arguments(attribute, type, **options) if type.is_a? Symbol @errors.any? { |error| error.strict_match?(attribute, type, **options) } else messages_for(attribute).include?(type) end end
as_json(选项 = nil) 链接
返回一个 Hash
,可用作此对象的 JSON 表示。您可以传递 :full_messages
选项。这决定了 JSON 对象是否应包含完整消息(默认情况下为 false)。
person.errors.as_json # => {:name=>["cannot be nil"]}
person.errors.as_json(full_messages: true) # => {:name=>["name cannot be nil"]}
源代码: 显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 247 def as_json(options = nil) to_hash(options && options[:full_messages]) end
attribute_names() 链接
返回所有错误属性名称
person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
person.errors.attribute_names # => [:name]
源代码: 显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 237 def attribute_names @errors.map(&:attribute).uniq.freeze end
clear 链接
清除所有错误。但是,清除错误并不会使模型有效。下次运行验证时(例如,通过 ActiveRecord::Validations#valid?
),如果任何验证失败,错误集合将再次填充。
源代码: 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 80
delete(attribute, type = nil, **options) 链接
删除 key
的消息。返回已删除的消息。
person.errors[:name] # => ["cannot be nil"]
person.errors.delete(:name) # => ["cannot be nil"]
person.errors[:name] # => []
源代码: 显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 215 def delete(attribute, type = nil, **options) attribute, type, options = normalize_arguments(attribute, type, **options) matches = where(attribute, type, **options) matches.each do |error| @errors.delete(error) end matches.map(&:message).presence end
details() 链接
返回一个 Hash
,其中包含带有其错误详细信息数组的属性。
源代码: 显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 276 def details hash = group_by_attribute.transform_values do |errors| errors.map(&:details) end hash.default = EMPTY_ARRAY hash.freeze hash end
each(&block) 链接
遍历每个错误对象。
person.errors.add(:name, :too_short, count: 2)
person.errors.each do |error|
# Will yield <#ActiveModel::Error attribute=name, type=too_short,
options={:count=>3}>
end
源代码: 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 67
full_message(attribute, message) 链接
返回给定属性的完整消息。
person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 451 def full_message(attribute, message) Error.full_message(attribute, message, @base) end
full_messages() 链接
以数组的形式返回所有完整错误消息。
class Person
validates_presence_of :name, :address, :email
validates_length_of :name, in: 5..30
end
person = Person.create(address: '123 First St.')
person.errors.full_messages
# => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 415 def full_messages @errors.map(&:full_message) end
full_messages_for(attribute) 链接
以数组的形式返回给定属性的所有完整错误消息。
class Person
validates_presence_of :name, :email
validates_length_of :name, in: 5..30
end
person = Person.create()
person.errors.full_messages_for(:name)
# => ["Name is too short (minimum is 5 characters)", "Name can't be blank"]
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 430 def full_messages_for(attribute) where(attribute).map(&:full_message).freeze end
generate_message(attribute, type = :invalid, options = {}) 链接
在默认范围内(activemodel.errors.messages
)翻译错误消息。
Error
消息首先在 activemodel.errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE
中查找,如果不存在,则在 activemodel.errors.models.MODEL.MESSAGE
中查找,如果也不存在,则返回默认消息的翻译(例如 activemodel.errors.messages.MESSAGE
)。已翻译的模型名称、已翻译的属性名称和值可用于插值。
在模型中使用继承时,它也会检查所有继承的模型,但前提是尚未找到模型本身。假设你有 class Admin < User; end
,并且你想要 title
属性的 :blank
错误消息的翻译,它会查找以下翻译
-
activemodel.errors.models.admin.attributes.title.blank
-
activemodel.errors.models.admin.blank
-
activemodel.errors.models.user.attributes.title.blank
-
activemodel.errors.models.user.blank
-
通过
options
哈希(在activemodel.errors
范围内)提供的任何默认值 -
activemodel.errors.messages.blank
-
errors.attributes.title.blank
-
errors.messages.blank
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 479 def generate_message(attribute, type = :invalid, options = {}) Error.generate_message(attribute, type, @base, options) end
group_by_attribute() 链接
返回一个 Hash
,其中包含属性及其 Error
对象数组。
person.errors.group_by_attribute
# => {:name=>[<#ActiveModel::Error>, <#ActiveModel::Error>]}
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 289 def group_by_attribute @errors.group_by(&:attribute) end
import(error, override_options = {}) 链接
导入一个错误。导入的错误将包装为 NestedError
,提供对原始错误对象的访问。如果需要覆盖属性或类型,请使用 override_options
。
选项
-
:attribute
- 覆盖错误所属的属性。 -
:type
- 覆盖错误的类型。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 154 def import(error, override_options = {}) [:attribute, :type].each do |key| if override_options.key?(key) override_options[key] = override_options[key].to_sym end end @errors.append(NestedError.new(@base, error, override_options)) end
include?(attribute) 链接
如果错误消息包含给定键 attribute
的错误,则返回 true
,否则返回 false
。
person.errors.messages # => {:name=>["cannot be nil"]}
person.errors.include?(:name) # => true
person.errors.include?(:age) # => false
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 202 def include?(attribute) @errors.any? { |error| error.match?(attribute.to_sym) } end
merge!(other) 链接
合并来自 other
的错误,每个 Error
都包装为 NestedError
。
参数
-
other
-ActiveModel::Errors
实例。
示例
person.errors.merge!(other)
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 174 def merge!(other) return errors if equal?(other) other.errors.each { |error| import(error) } end
messages() 链接
返回一个 Hash
,其中包含带有其错误消息数组的属性。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 268 def messages hash = to_hash hash.default = EMPTY_ARRAY hash.freeze hash end
messages_for(attribute) 链接
返回给定属性的所有错误消息,形式为数组。
class Person
validates_presence_of :name, :email
validates_length_of :name, in: 5..30
end
person = Person.create()
person.errors.messages_for(:name)
# => ["is too short (minimum is 5 characters)", "can't be blank"]
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 444 def messages_for(attribute) where(attribute).map(&:message) end
of_kind?(attribute, type = :invalid) 链接
如果存在具有给定类型的属性上的错误,则返回 true
,否则返回 false
。type
的处理方式与 add
相同。
person.errors.add :age
person.errors.add :name, :too_long, count: 25
person.errors.of_kind? :age # => true
person.errors.of_kind? :name # => false
person.errors.of_kind? :name, :too_long # => true
person.errors.of_kind? :name, "is too long (maximum is 25 characters)" # => true
person.errors.of_kind? :name, :not_too_long # => false
person.errors.of_kind? :name, "is too long" # => false
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 395 def of_kind?(attribute, type = :invalid) attribute, type = normalize_arguments(attribute, type) if type.is_a? Symbol !where(attribute, type).empty? else messages_for(attribute).include?(type) end end
size 链接
返回错误数。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 103 def_delegators :@errors, :each, :clear, :empty?, :size, :uniq!
to_hash(full_messages = false) 链接
返回一个包含属性及其错误消息的 Hash
。如果 full_messages
为 true
,它将包含完整消息(请参阅 full_message
)。
person.errors.to_hash # => {:name=>["cannot be nil"]}
person.errors.to_hash(true) # => {:name=>["name cannot be nil"]}
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 256 def to_hash(full_messages = false) message_method = full_messages ? :full_message : :message group_by_attribute.transform_values do |errors| errors.map(&message_method) end end
where(attribute, type = nil, **options) 链接
搜索与 attribute
、type
或 options
匹配的错误。
仅匹配提供的参数。
person.errors.where(:name) # => all name errors.
person.errors.where(:name, :too_short) # => all name errors being too short
person.errors.where(:name, :too_short, minimum: 2) # => all name errors being too short and minimum is 2
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/errors.rb, line 189 def where(attribute, type = nil, **options) attribute, type, options = normalize_arguments(attribute, type, **options) @errors.select { |error| error.match?(attribute, type, **options) } end