Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby JSON parse changes Hash keys

Lets say I have this Hash:

{   :info => [     {         :from => "Ryan Bates",         :message => "sup bra",         :time => "04:35 AM"     }   ] } 

I can call the info array by doing hash[:info].

Now when I turn this into JSON (JSON.generate), and then parse it (JSON.parse), I get this hash:

{   "info" => [     {         "from" => "Ryan Bates",         "message" => "sup bra",         "time" => "04:35 AM"     }   ] } 

Now if I use hash[:info] it returns nil, but not if I use hash["info"].

Why is this? And is there anyway to fix this incompatibility (besides using string keys from the start)?

like image 794
LanguagesNamedAfterCofee Avatar asked Sep 25 '11 05:09

LanguagesNamedAfterCofee


People also ask

How to parse a JSON in Ruby?

user_info = JSON. parse(file); Once we have the file parsed into a Ruby Hash, we can use built-in methods to manipulate the values. This should print the hash keys which are basically the JSON keys.

What does JSON parse return in Ruby?

Returns the JSON parser class that is used by JSON. This is either JSON::Ext::Parser or JSON::Pure::Parser. Returns the JSON generator state class that is used by JSON.

Is JSON parse safe Ruby?

There are no security concerns possible. JSON isn't code, you can't inject harmful values into it. JSON. parse is safe.

How to parse JSON in Rails?

One way to use rails to parse json in a scalable and effective manner is to create a class that parses the JSON response and manages the data from the json fields using the object. The problem with this approach is we need to maintain the class and have to be clear on which fields are included in the JSON.


2 Answers

The JSON generator converts symbols to strings because JSON does not support symbols. Since JSON keys are all strings, parsing a JSON document will produce a Ruby hash with string keys by default.

You can tell the parser to use symbols instead of strings by using the symbolize_names option.

Example:

original_hash = {:info => [{:from => "Ryan Bates", :message => "sup bra", :time => "04:35 AM"}]} serialized = JSON.generate(original_hash) new_hash = JSON.parse(serialized, {:symbolize_names => true})  new_hash[:info]  #=> [{:from=>"Ryan Bates", :message=>"sup bra", :time=>"04:35 AM"}] 

Reference: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-parse

like image 198
wyattisimo Avatar answered Sep 18 '22 14:09

wyattisimo


In short, no. Think about it this way, storing symbols in JSON is the same as storing strings in JSON. So you cannot possibly distinguish between the two when it comes to parsing the JSON string. You can of course convert the string keys back into symbols, or in fact even build a class to interact with JSON which does this automagically, but I would recommend just using strings.

But, just for the sake of it, here are the answers to this question the previous times it's been asked:

what is the best way to convert a json formatted key value pair to ruby hash with symbol as key?

ActiveSupport::JSON decode hash losing symbols

Or perhaps a HashWithIndifferentAccess

like image 26
Lee Jarvis Avatar answered Sep 16 '22 14:09

Lee Jarvis