diff --git a/lib/active_resource/validations.rb b/lib/active_resource/validations.rb index fee1525d92..8c1fca8ab6 100644 --- a/lib/active_resource/validations.rb +++ b/lib/active_resource/validations.rb @@ -14,16 +14,18 @@ class Errors < ActiveModel::Errors # The second parameter directs the errors cache to be cleared (default) # or not (by passing true). def from_array(messages, save_cache = false) - clear unless save_cache + errors = Hash.new { |hash, attr_name| hash[attr_name] = [] } humanized_attributes = Hash[@base.known_attributes.map { |attr_name| [ attr_name.humanize, attr_name ] }] - messages.each do |message| + messages.each_with_object(errors) do |message, hash| attr_message = humanized_attributes.keys.sort_by { |a| -a.length }.detect do |attr_name| if message[0, attr_name.size + 1] == "#{attr_name} " - add humanized_attributes[attr_name], message[(attr_name.size + 1)..-1] + hash[humanized_attributes[attr_name]] << message[(attr_name.size + 1)..-1] end end - add(:base, message) if attr_message.nil? + hash["base"] << message if attr_message.nil? end + + from_hash errors, save_cache end # Grabs errors from a hash of attribute => array of errors elements diff --git a/test/cases/validations_test.rb b/test/cases/validations_test.rb index b4e2b92803..84e1d5fbe5 100644 --- a/test/cases/validations_test.rb +++ b/test/cases/validations_test.rb @@ -76,3 +76,61 @@ def new_project(opts = {}) Project.new(VALID_PROJECT_HASH.merge(opts)) end end + +class ErrorsTest < ActiveSupport::TestCase + def test_from_xml_with_multiple_errors + errors = Project.new.errors + + errors.from_xml %q(Name can't be blankEmail can't be blank) + + assert_equal [ "can't be blank" ], errors[:name] + assert_equal [ "can't be blank" ], errors[:email] + end + + def test_from_xml_with_one_error + errors = Project.new.errors + + errors.from_xml %q(Name can't be blank) + + assert_equal [ "can't be blank" ], errors[:name] + end + + def test_from_json + errors = Project.new.errors + + errors.from_json %q({"errors":{"name":["can't be blank"],"email":["can't be blank"]}}) + + assert_equal [ "can't be blank" ], errors[:name] + assert_equal [ "can't be blank" ], errors[:email] + end + + def test_from_hash + errors = Project.new.errors + + errors.from_hash( + "base" => [ "has an error" ], + "unknown" => [ "is invalid" ], + "name" => [ "can't be blank" ], + "email" => [ "can't be blank" ] + ) + + assert_equal [ "has an error", "Unknown is invalid" ], errors[:base] + assert_equal [ "can't be blank" ], errors[:name] + assert_equal [ "can't be blank" ], errors[:email] + end + + def test_from_array + errors = Project.new.errors + + errors.from_array [ + "Unknown is invalid", + "Base has an error", + "Name can't be blank", + "Email can't be blank" + ] + + assert_equal [ "Unknown is invalid", "Base has an error" ], errors[:base] + assert_equal [ "can't be blank" ], errors[:name] + assert_equal [ "can't be blank" ], errors[:email] + end +end