ActiveModel::Errors inherits from hash and behaves unexpectedly

ActiveModel::Errors is used to handle validation errors on Rails objects. If you inspect an instance, it feels like a hash (to be more precise, it inherits from Hash):

errors = ActiveModel::Errors.new(Object.new)
=> {}
>> 
?> errors.add(:base, "foo")
=> ["foo"]
>> errors.add(:base, "bar")
=> ["foo", "bar"]
>> 
?> errors
=> {:base=>["foo", "bar"]}

If you need to hack anything with these errors, beware that it behaves in a special way. If you iterate over the errors it will decompose arrays.
For attributes with multiple errors such as :base => ["foo", "bar"] it yields once per value ("foo" and "bar" here) within the array and not per key.

>> for k,v in errors do
>>   puts k
>>   puts v
>>   puts "--"
>> end

base
foo
--
base
bar
--

In contrast, a hash simply yields once per key giving you only the array as value.

Thomas Eisenbarth