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"=>"[email protected]",
      "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"=>"[email protected]", "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].

2
  • 1
    there is deep_symbolize_keys - exactly for these purposes ;) Commented Feb 19, 2017 at 17:48
  • @AndreyDeineko, that's for rails. The question is for ruby Commented Jul 9, 2021 at 20:54

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

4 Comments

I have tried symbolize_keys which only symbolize the first level keys
@LiXinyang did you try giving JSON.parse the parameter to symbolize_keys?
Thanks, deep_symolize_keys does the work. wonder if there is a pure Ruby solution.
According to this answer stackoverflow.com/questions/24927653/… you can use the symbolize_names parameter on JSON.parse to do it, I guess that's pure Ruby if you include json?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.