I need to extract some data from a JSON response i'm serving up from curb.

Previously I wasn't calling symbolize_keys, but i thought that would make my attempt work.

The controller action:

http = Curl.get("http://api.foobar.com/thing/thing_name/catalog_items.json?per_page=1&page=1") do|http|
  http.headers['X-Api-Key'] = 'georgeBushSucks'
end
pre_keys =  http.body_str
@foobar = ActiveSupport::JSON.decode(pre_keys).symbolize_keys

In the view (getting undefined method `current_price' )

@foobar.current_price

I also tried @foobar.data[0]['current_price'] with the same result

JSON response from action:

{
    "data": {
        "catalog_items": [
            {
                "current_price": "9999.0",
                "close_date": "2013-05-14T16:08:00-04:00",
                "open_date": "2013-04-24T11:00:00-04:00",
                "stuff_count": 82,
                "minimum_price": "590000.0",
                "id": 337478,
                "estimated_price": "50000.0",
                "name": "This is a really cool name",
                "current_winner_id": 696969,
                "images": [
                    {
                        "thumb_url": "http://foobar.com/images/93695/thumb.png?1365714300",
                        "detail_url": "http://foobar.com/images/93695/detail.png?1365714300",
                        "position": 1
                    },
                    {
                        "thumb_url": "http://foobar.com/images/95090/thumb.jpg?1366813823",
                        "detail_url": "http://foobar.com/images/95090/detail.jpg?1366813823",
                        "position": 2
                    }
                ]
            }
        ]
    },
    "pagination": {
        "per_page": 1,
        "page": 1,
        "total_pages": 131,
        "total_objects": 131
    }
}
有帮助吗?

解决方案

Please note that accessing hash's element in Rails work in models. To use it on hash, you have to use OpenStruct object. It's part of standard library in rails. Considering, @foobar has decoded JSON as you have.

obj = OpenStruct.new(@foobar)
obj.data
#=> Hash

But, note that, obj.data.catalog_items willn't work, because that is an hash, and again not an OpenStruct object. To aid this, we have recursive-open-struct, which will do the job for you.

Alternative solution [1]:

@foobar[:data]['catalog_items'].first['current_price']

But, ugly.

Alternative solution [2]:

Open Hash class, use method_missing ability as :

class Hash
  def method_missing(key)
    self[key.to_s]
  end
end

Hope it helps. :)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top