From ea77205a9ff71ebd0dc7cf29e598ef126c9807f5 Mon Sep 17 00:00:00 2001 From: lulalala Date: Mon, 26 Mar 2018 13:09:59 +0800 Subject: 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 --- activemodel/lib/active_model/errors.rb | 29 +++++++++-------------------- activemodel/test/cases/errors_test.rb | 8 ++++++++ 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'activemodel') 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, :invalid 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) -- cgit v1.2.3