3

The server is using JSON API which returns a nested data structure. I have tried to parse it using JSON.parse but it is converted the json string to string hash by default.

Sample Data

{
  "data"=>
  {
    "id"=>"1",
    "type"=>"users",
    "attributes"=>
    {
      "email"=>"tia_heller@lebsack.info",
      "name"=>"Tanner Kreiger"
    }
  }
}

I have tried code below but it only convert one level deep (not children hash)

  def json_body
    str_hash = JSON.parse(response.body)
    str_hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
  end

I have also tried symbolize_keys from Rails which only convert the first level as well (see :data and the rest is the same),

{:data=>{"id"=>"1", "type"=>"users", "attributes"=>{"email"=>"darrion_hackett@weberharvey.io", "name"=>"Cleo Braun"}}}

What is the best approach to recursively convert the nested string hash into symbol hash?

Desired Result

All the value can be access using symbol, like json_response[:data][:attributes].

XY L
  • 25,431
  • 14
  • 84
  • 143

1 Answers1

3

Just use

JSON.parse(result, symbolize_keys: true)

More info http://apidock.com/ruby/JSON/parse

or on the hash itself

hash = { 'name' => 'Rob', 'age' => '28' }

hash.symbolize_keys
# => {:name=>"Rob", :age=>"28"}

http://apidock.com/rails/Hash/symbolize_keys

These don't seem to do it recursively though.

There's also deep_symbolize_keys! in Rails

http://api.rubyonrails.org/classes/Hash.html#method-i-deep_symbolize_keys

Coolness
  • 1,932
  • 13
  • 25
  • 1
    I have tried `symbolize_keys` which only symbolize the first level keys – XY L Feb 19 '17 at 14:47
  • @LiXinyang did you try giving `JSON.parse` the parameter to symbolize_keys? – Coolness Feb 19 '17 at 14:51
  • 1
    Thanks, `deep_symolize_keys` does the work. wonder if there is a pure Ruby solution. – XY L Feb 19 '17 at 14:56
  • 1
    According to this answer http://stackoverflow.com/questions/24927653/how-to-elegantly-symbolize-keys-for-a-nested-hash you can use the `symbolize_names` parameter on `JSON.parse` to do it, I guess that's pure Ruby if you include `json`? – Coolness Feb 19 '17 at 15:20