1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add convenience method group_by_attribute

Many operations need grouping of errors by attributes, e.g. ActiveRecord::AutosaveAssociation#association_valid?

Refactor other methods using group_by_attribute
This commit is contained in:
lulalala 2018-03-26 13:09:59 +08:00
parent d9011e3935
commit ea77205a9f
2 changed files with 17 additions and 20 deletions

View file

@ -292,18 +292,9 @@ module ActiveModel
# person.errors.to_hash(true) # => {:name=>["name cannot be nil"]} # person.errors.to_hash(true) # => {:name=>["name cannot be nil"]}
def to_hash(full_messages = false) def to_hash(full_messages = false)
hash = {} hash = {}
@errors.each do |error| message_method = full_messages ? :full_message : :message
if full_messages group_by_attribute.each do |attribute, errors|
message = error.full_message hash[attribute] = errors.map(&message_method)
else
message = error.message
end
if hash.has_key?(error.attribute)
hash[error.attribute] << message
else
hash[error.attribute] = [message]
end
end end
hash hash
end end
@ -311,18 +302,16 @@ module ActiveModel
def details def details
hash = {} hash = {}
@errors.each do |error| group_by_attribute.each do |attribute, errors|
detail = error.detail hash[attribute] = errors.map(&:detail)
if hash.has_key?(error.attribute)
hash[error.attribute] << detail
else
hash[error.attribute] = [detail]
end
end end
hash hash
end end
def group_by_attribute
group_by(&:attribute)
end
# Adds +message+ to the error messages and used validator type to +details+ on +attribute+. # Adds +message+ to the error messages and used validator type to +details+ on +attribute+.
# More than one error can be added to the same +attribute+. # More than one error can be added to the same +attribute+.
# If no +message+ is supplied, <tt>:invalid</tt> is assumed. # If no +message+ is supplied, <tt>:invalid</tt> is assumed.

View file

@ -494,6 +494,14 @@ class ErrorsTest < ActiveModel::TestCase
assert_equal({ name: [{ error: :invalid }] }, person.errors.details) assert_equal({ name: [{ error: :invalid }] }, person.errors.details)
end end
test "group_by_attribute" do
person = Person.new
error = person.errors.add(:name, :invalid, message: "is bad")
hash = person.errors.group_by_attribute
assert_equal({ name: [error] }, hash)
end
test "dup duplicates details" do test "dup duplicates details" do
errors = ActiveModel::Errors.new(Person.new) errors = ActiveModel::Errors.new(Person.new)
errors.add(:name, :invalid) errors.add(:name, :invalid)