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

Allow errors to remove duplicates, and ensure cyclic associations w/ autosave duplicate errors can be removed

See SHA 7550f0a016
This commit is contained in:
lulalala 2018-04-03 13:06:04 +08:00
parent 2a06f13099
commit 86620cc3aa
4 changed files with 37 additions and 4 deletions

View file

@ -62,5 +62,20 @@ module ActiveModel
full_message == Error.new(@base, attribute, type, **options).full_message
end
def ==(other)
attributes_for_hash == other.attributes_for_hash
end
alias eql? ==
def hash
attributes_for_hash.hash
end
protected
def attributes_for_hash
[@base, @attribute, @raw_type, @options]
end
end
end

View file

@ -64,7 +64,7 @@ module ActiveModel
include Enumerable
extend Forwardable
def_delegators :@errors, :size, :clear, :blank?, :empty?
def_delegators :@errors, :size, :clear, :blank?, :empty?, :uniq!
# TODO: forward all enumerable methods after `each` deprecation is removed.
def_delegators :@errors, :count

View file

@ -170,4 +170,24 @@ class ErrorTest < ActiveModel::TestCase
assert_equal "name can't be blank", error.full_message
}
end
test "equality by base attribute, type and options" do
person = Person.new
e1 = ActiveModel::Error.new(person, :name, foo: :bar)
e2 = ActiveModel::Error.new(person, :name, foo: :bar)
e2.instance_variable_set(:@_humanized_attribute, "Name")
assert_equal(e1, e2)
end
test "inequality" do
person = Person.new
error = ActiveModel::Error.new(person, :name, foo: :bar)
assert error != ActiveModel::Error.new(person, :name, foo: :baz)
assert error != ActiveModel::Error.new(person, :name)
assert error != ActiveModel::Error.new(person, :title, foo: :bar)
assert error != ActiveModel::Error.new(Person.new, :name, foo: :bar)
end
end

View file

@ -491,9 +491,7 @@ module ActiveRecord
end
def _ensure_no_duplicate_errors
errors.messages.each_key do |attribute|
errors[attribute].uniq!
end
errors.uniq!
end
end
end