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
实例公共方法
[](attribute) 链接
当传入一个符号或一个方法名称时,返回该方法的错误数组。
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(attribute, type = :invalid, **options) 链接
在 attribute
上添加一个新的 type
错误。可以向同一个 attribute
添加多个错误。如果没有提供 type
,则假定为 :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"]}
如果 type
是一个字符串,它将用作错误消息。
如果 type
是一个符号,它将使用适当的范围进行翻译(参见 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)"]
如果 type
是一个 proc,它将被调用,允许在错误中使用诸如 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 # => {}
如果错误不直接与单个属性相关联,则 attribute
应设置为 :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?(attribute, type = :invalid, options = {}) 链接
如果错误与提供的 attribute
和 type
匹配,则返回 true
,否则返回 false
。type
的处理方式与 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(options = nil) 链接
返回一个 哈希
,它可以作为此对象的 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() 链接
返回一个 哈希
,其中包含属性与其错误详细信息的数组。
来源: 显示 | 在 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
)中翻译错误消息。
错误
消息首先在 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() 链接
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 = {}) 链接
导入一个错误。导入的错误被包装为 嵌套错误
,提供对原始错误对象的访问。如果需要覆盖属性或类型,请使用 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