Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix ActiveModel::Errors#dup

Since ActiveModel::Errors instance keeps all error messages as hash
we should duplicate this object as well.

Previously ActiveModel::Errors was a subclass of ActiveSupport::OrderedHash,
which results in different behavior on dup, this may result in regression for
people relying on it.

Because Rails 3.2 stills supports Ruby 1.8.7 in order to properly fix this
regression we need to backport #initialize_dup.
  • Loading branch information...
commit 5da6b6ed672cead5ece53ecab248fe3fdcc3503a 1 parent f34e5a7
Paweł Kondzior pkondzior authored drogus committed
15 activemodel/lib/active_model/errors.rb
View
@@ -79,6 +79,19 @@ def initialize(base)
@messages = ActiveSupport::OrderedHash.new
end
+ def initialize_dup(other)
+ @messages = other.messages.dup
+ end
+
+ # Backport dup from 1.9 so that #initialize_dup gets called
+ unless Object.respond_to?(:initialize_dup)
+ def dup # :nodoc:
+ copy = super
+ copy.initialize_dup(self)
+ copy
+ end
+ end
+
# Clear the messages
def clear
messages.clear
@@ -118,7 +131,7 @@ def [](attribute)
# p.errors[:name] = "must be set"
# p.errors[:name] # => ['must be set']
def []=(attribute, error)
- self[attribute.to_sym] << error
+ self[attribute] << error
end
# Iterates through each error key, value pair in the error messages hash.
8 activemodel/test/cases/errors_test.rb
View
@@ -40,6 +40,14 @@ def test_include?
assert errors.include?(:foo), 'errors should include :foo'
end
+ def test_dup
+ errors = ActiveModel::Errors.new(self)
+ errors[:foo] = 'bar'
+ errors_dup = errors.dup
+ errors_dup[:bar] = 'omg'
+ assert_not_same errors_dup.messages, errors.messages
+ end
+
test "should return true if no errors" do
person = Person.new
person.errors[:foo]
Please sign in to comment.
Something went wrong with that request. Please try again.