aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorlulalala <mark@goodlife.tw>2018-03-26 13:09:59 +0800
committerlulalala <mark@goodlife.tw>2019-03-31 22:59:12 +0800
commitea77205a9ff71ebd0dc7cf29e598ef126c9807f5 (patch)
tree88ced0b2f6e744fe4aef87faa2708d55cbf5bd9f /activemodel
parentd9011e39357300fe78720227af4c13b4bc4ac4dd (diff)
downloadrails-ea77205a9ff71ebd0dc7cf29e598ef126c9807f5.tar.gz
rails-ea77205a9ff71ebd0dc7cf29e598ef126c9807f5.tar.bz2
rails-ea77205a9ff71ebd0dc7cf29e598ef126c9807f5.zip
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
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/lib/active_model/errors.rb29
-rw-r--r--activemodel/test/cases/errors_test.rb8
2 files changed, 17 insertions, 20 deletions
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index a0b3b0ab54..9800d9305e 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -292,18 +292,9 @@ module ActiveModel
# person.errors.to_hash(true) # => {:name=>["name cannot be nil"]}
def to_hash(full_messages = false)
hash = {}
- @errors.each do |error|
- if full_messages
- message = error.full_message
- else
- message = error.message
- end
-
- if hash.has_key?(error.attribute)
- hash[error.attribute] << message
- else
- hash[error.attribute] = [message]
- end
+ message_method = full_messages ? :full_message : :message
+ group_by_attribute.each do |attribute, errors|
+ hash[attribute] = errors.map(&message_method)
end
hash
end
@@ -311,18 +302,16 @@ module ActiveModel
def details
hash = {}
- @errors.each do |error|
- detail = error.detail
-
- if hash.has_key?(error.attribute)
- hash[error.attribute] << detail
- else
- hash[error.attribute] = [detail]
- end
+ group_by_attribute.each do |attribute, errors|
+ hash[attribute] = errors.map(&:detail)
end
hash
end
+ def group_by_attribute
+ group_by(&:attribute)
+ end
+
# 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+.
# If no +message+ is supplied, <tt>:invalid</tt> is assumed.
diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb
index a6fd95d7b1..58aa7ee147 100644
--- a/activemodel/test/cases/errors_test.rb
+++ b/activemodel/test/cases/errors_test.rb
@@ -494,6 +494,14 @@ class ErrorsTest < ActiveModel::TestCase
assert_equal({ name: [{ error: :invalid }] }, person.errors.details)
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
errors = ActiveModel::Errors.new(Person.new)
errors.add(:name, :invalid)