Active Resource responses, how to get them

2019-04-06 15:01发布

问题:

I have an Active Resource that I query for data. It returns records, counts, whatever I ask for.

eg: product = Product.find(123)

The response headers supposedly contain a custom attribute, say "HTTP_PRODUCT_COUNT=20" and I would like to examine the response.

What would be the most efficient way of doing this from IRB? I don't have the luxury of Rails or other frameworks that might provide the underlying response.

Do I need to hack Net::HTTP or ActiveResource itself with a monkeypatched call or something?

回答1:

Here's one way to do it without monkeypatching.

class MyConn < ActiveResource::Connection
  attr_reader :last_resp
  def handle_response(resp)
    @last_resp=resp
    super
  end
end

class Item < ActiveResource::Base
  class << self
    attr_writer :connection
  end
  self.site = 'http://yoursite'
end

# Set up our own connection
myconn = MyConn.new Item.connection.site
Item.connection = myconn  # replace with our enhanced version
item = Item.find(123)
# you can also access myconn via Item.connection, since we've assigned it
myconn.last_resp.code  # response code
myconn.last_resp.to_hash  # header

If you change certain class fields like site, ARes will re-assign the connection field with a new Connection object. To see when this happens, search active_resource/base.rb for where @connection is set to nil. In these cases you'll have to assign the connection again.

UPDATE: Here's a modified MyConn that should be thread-safe. (re-edited with fivell's suggestion)

class MyConn < ActiveResource::Connection
  def handle_response(resp)
    # Store in thread (thanks fivell for the tip).
    # Use a symbol to avoid generating multiple string instances.
    Thread.current[:active_resource_connection_last_response] = resp
    super
  end
  # this is only a convenience method. You can access this directly from the current thread.
  def last_resp
    Thread.current[:active_resource_connection_last_response]
  end
end


回答2:

module ActiveResource
  class Connection
    alias_method :origin_handle_response, :handle_response 
    def handle_response(response)
        Thread.current[:active_resource_connection_headers]  = response
        origin_handle_response(response)
    end  

    def response
      Thread.current[:active_resource_connection_headers]
    end   

  end
end    

also you can try this gem https://github.com/Fivell/activeresource-response