From 3650ca983c5c2ffd1a2993fa091bf504594325a7 Mon Sep 17 00:00:00 2001 From: Jahfer Husain Date: Fri, 7 Jul 2017 13:16:06 -0400 Subject: [PATCH] Add ActiveModel::Errors#merge! ActiveModel::Errors#merge! allows ActiveModel::Errors to append errors from a separate ActiveModel::Errors instance onto their own. Example: person = Person.new person.errors.add(:name, :blank) errors = ActiveModel::Errors.new(Person.new) errors.add(:name, :invalid) person.errors.merge!(errors) puts person.errors.messages # => { name: ["can't be blank", "is invalid"] } --- activemodel/CHANGELOG.md | 4 ++++ activemodel/lib/active_model/errors.rb | 12 ++++++++++++ activemodel/test/cases/errors_test.rb | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 2916e5eabb..048c43f2c4 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,7 @@ +* Add method `#merge!` for `ActiveModel::Errors`. + + *Jahfer Husain* + * Fix regression in numericality validator when comparing Decimal and Float input values with more scale than the schema. diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 942b4fa9bb..76c23df541 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -93,6 +93,18 @@ module ActiveModel @details = other.details.dup end + # Merges the errors from other. + # + # other - The ActiveModel::Errors instance. + # + # Examples + # + # person.errors.merge!(other) + def merge!(other) + @messages.merge!(other.messages) { |_, ary1, ary2| ary1 + ary2 } + @details.merge!(other.details) { |_, ary1, ary2| ary1 + ary2 } + end + # Clear the error messages. # # person.errors.full_messages # => ["name cannot be nil"] diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 43aee5a814..7383b3e9b0 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -375,6 +375,18 @@ class ErrorsTest < ActiveModel::TestCase assert_equal [:name], person.errors.details.keys end + test "merge errors" do + errors = ActiveModel::Errors.new(Person.new) + errors.add(:name, :invalid) + + person = Person.new + person.errors.add(:name, :blank) + person.errors.merge!(errors) + + assert_equal({ name: ["can't be blank", "is invalid"] }, person.errors.messages) + assert_equal({ name: [{ error: :blank }, { error: :invalid }] }, person.errors.details) + end + test "errors are marshalable" do errors = ActiveModel::Errors.new(Person.new) errors.add(:name, :invalid)