whichdigital / active-rest-client

ActiveRestClient API Client
https://rubygems.org/gems/active_rest_client
MIT License
385 stars 44 forks source link

Unable to set 'response.body' in 'after_request' callback #85

Open dekhaus opened 9 years ago

dekhaus commented 9 years ago

In order to conform to the REST conventions of a Rails app - specifically a 'GET index' results contain a 'root' node corresponding to the 'underscorerized / pluralized' name of the resource - I need to add an 'after_request' callback.

While experimenting with implementing this callback - I thought I'd try the 'base' case listed in the documentation ...

class Person < ActiveRestClient::Base after_request :fix_empty_content

private

def fix_empty_content(name, response) if response.status == 204 && response.body.blank? response.body = '{"empty": true}' end end end

This doesn't work and returns this error ...

NoMethodError: undefined method body=' for #<Faraday::Response:0x007f9361ac9058> from /Users/dekhaus/projects/rails4/groot/app/models/wip_model.rb:26:inadjust_body'

Presumably - because no setter exists for the 'body' attribute.

Regards, Dave

dkarter commented 9 years ago

This is how I change the body of the request before it is being serialized into ARC objects (using proxy):

module Proxies
    class ProxyBase < ActiveRestClient::ProxyBase
      def self.underscore_key(string)
        string.gsub(/::/, '/')
          .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
          .gsub(/([a-z\d])([A-Z])/, '\1_\2')
          .tr('-', '_')
          .downcase
      end

      def self.convert_hash_keys(value)
        case value
        when Array
          value.map { |v| convert_hash_keys(v) }
        when Hash
          Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
        else
          value
        end
      end

      # converts camelCase keys to snake_case symbols
      get(/.*/) do
        response = passthrough
        translate(response) do |body|
          convert_hash_keys(body)
        end
      end
    end
  end

To set the proxy on a class:

module Resources
    class List < ActiveRestClient::Base
      proxy Proxies::ProxyBase
    end
end