diff options
Diffstat (limited to 'activeresource/lib')
-rw-r--r-- | activeresource/lib/active_resource/base.rb | 13 | ||||
-rw-r--r-- | activeresource/lib/active_resource/validations.rb | 42 |
2 files changed, 51 insertions, 4 deletions
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index c0d51797ee..5ef50b6e03 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -234,7 +234,7 @@ module ActiveResource # ryan.save # => false # # # When - # # PUT https://api.people.com/people/1.json + # # PUT https://api.people.com/people/1.xml # # or # # PUT https://api.people.com/people/1.json # # is requested with invalid values, the response is: @@ -242,12 +242,21 @@ module ActiveResource # # Response (422): # # <errors><error>First cannot be empty</error></errors> # # or - # # {"errors":["First cannot be empty"]} + # # {"errors":{"first":["cannot be empty"]}} # # # # ryan.errors.invalid?(:first) # => true # ryan.errors.full_messages # => ['First cannot be empty'] # + # For backwards-compatibility with older endpoints, the following formats are also supported in JSON responses: + # + # # {"errors":['First cannot be empty']} + # # This was the required format for previous versions of ActiveResource + # # {"first":["cannot be empty"]} + # # This was the default format produced by respond_with in ActionController <3.2.1 + # + # Parsing either of these formats will result in a deprecation warning. + # # Learn more about Active Resource's validation features in the ActiveResource::Validations documentation. # # === Timeouts diff --git a/activeresource/lib/active_resource/validations.rb b/activeresource/lib/active_resource/validations.rb index a63f02cb57..028acb8bce 100644 --- a/activeresource/lib/active_resource/validations.rb +++ b/activeresource/lib/active_resource/validations.rb @@ -25,10 +25,48 @@ module ActiveResource end end + # Grabs errors from a hash of attribute => array of errors elements + # The second parameter directs the errors cache to be cleared (default) + # or not (by passing true) + # + # Unrecognized attribute names will be humanized and added to the record's + # base errors. + def from_hash(messages, save_cache = false) + clear unless save_cache + + messages.each do |(key,errors)| + errors.each do |error| + if @base.attributes.keys.include?(key) + add key, error + elsif key == 'base' + self[:base] << error + else + # reporting an error on an attribute not in attributes + # format and add them to base + self[:base] << "#{key.humanize} #{error}" + end + end + end + end + # Grabs errors from a json response. def from_json(json, save_cache = false) - array = Array.wrap(ActiveSupport::JSON.decode(json)['errors']) rescue [] - from_array array, save_cache + decoded = ActiveSupport::JSON.decode(json) || {} rescue {} + if decoded.kind_of?(Hash) && (decoded.has_key?('errors') || decoded.empty?) + errors = decoded['errors'] || {} + if errors.kind_of?(Array) + # 3.2.1-style with array of strings + ActiveSupport::Deprecation.warn('Returning errors as an array of strings is deprecated.') + from_array errors, save_cache + else + # 3.2.2+ style + from_hash errors, save_cache + end + else + # <3.2-style respond_with - lacks 'errors' key + ActiveSupport::Deprecation.warn('Returning errors as a hash without a root "errors" key is deprecated.') + from_hash decoded, save_cache + end end # Grabs errors from an XML response. |