26

Possible Duplicate:
Parsing a JSON string in ruby

Is it possible to convert a JSON string into a Ruby object? I would like to access its information with an expression similar to:

drawer.stations.tv.header

JSON string:

{
  "drawer" : {
    "stations" : {
      "tv" : {
        "header" : "TV Channels",
        "logos" : {
          "one" : "www1",
          "two" : "www2",
          "three" : "www3"
        }
      }
    }
  }
}
2
  • Hiya, kind of... but not quite, ie, that one is just parsing the JSON but not converting the has into an object. So depending on what your needs are you could be fine with that explanation or use the explanation here, which is different... Commented Dec 17, 2012 at 19:34
  • 2
    I do not believe this is a duplicate, due to his request to access the keys as methods. For this, the recommend the answer from Sergio Tulentsev. Commented Jul 10, 2015 at 20:20

3 Answers 3

56

You can parse the string into a ruby hash and then turn it into a Mash. Mash provides you with method-like access.

require 'json'
require 'hashie'

hash = JSON.parse json_string
obj = Hashie::Mash.new hash
obj.drawer.stations.tv.header # => "TV Channels"

Update

You can also do it without a 3rd party gem, using ruby's own OpenStruct:

require 'ostruct'
require 'json'

obj = JSON.parse(json_string, object_class: OpenStruct)
obj.drawer.stations.tv.header # => "TV Channels"
Sign up to request clarification or add additional context in comments.

10 Comments

Great the Hashie. Mutch better than method_missing. Thanks for the tip.
Hey Sergio, gracias!!!! Thanks for taking the time to reply even though I accepted a previous answer as valid. That one was not bad, as a workaround. But your explanation is exactly what I was looking for... many thanks!!!!
Some API's may return a json array of hashes. In that case use something like @users = JSON.parse(resource.get).map { |hash| Hashie::Mash.new(hash) }
@Hal50000: check out the update :)
@SergioTulentsev nice! I just changed my code to use OpenStruct since it will handle both cases without manually wrangling the hashes
|
9

if your parse this string to ruby object, it will return a ruby Hash object, you can get it like this

  ruby_obj = JSON.parse(json_string)
  ruby_obj['drawer']['stations']['tv']['header']

3 Comments

It's considered bad form to troll for upvotes or selected answers.
@mickael Dude, upvote this guy. He needs the rep!! :P
Yeap, I was going to vote the answer but apparently stackoverflow doesn't allow you to do that before 20mins or so, so I had to wait a little, sorted now :)
3
require 'json'

json_info = %q(
{
  "drawer" : {
    "stations" : {
      "tv" : {
        "header" : "TV Channels",
        "logos" : {
          "one" : "www1",
          "two" : "www2",
          "three" : "www3"
        }
      }
    }
  }
}
)

class MyJson
    def self.for(p_jason_string)
        self.new(JSON.parse(p_jason_string))
    end

    def initialize(p_info)
        @info = p_info
    end

    def inspect
        @info.inspect
    end

    def method_missing(p_missing_method_name)
        print 'mm '; p p_missing_method_name
        key = p_missing_method_name.to_s

        if @info.has_key?(key)
        then
            MyJson.new(@info[key])
        else
            puts "no key #{p_missing_method_name}"
        end
    end
end # class MyJson

holder = MyJson.for(json_info)
puts '-----holder.drawer'
p holder.drawer
puts '-----holder.drawer.stations'
p holder.drawer.stations
puts '-----holder.drawer.stations.tv.header'
p holder.drawer.stations.tv.header

Execution :

$ ruby -v
ruby 1.9.2p320 (2012-04-20 revision 35421) [x86_64-darwin12.2.0]
$ ruby -w t.rb
-----holder.drawer
mm :drawer
{"stations"=>{"tv"=>{"header"=>"TV Channels", "logos"=>{"one"=>"www1", "two"=>"www2", "three"=>"www3"}}}}
-----holder.drawer.stations
mm :drawer
mm :stations
{"tv"=>{"header"=>"TV Channels", "logos"=>{"one"=>"www1", "two"=>"www2", "three"=>"www3"}}}
-----holder.drawer.stations.tv.header
mm :drawer
mm :stations
mm :tv
mm :header
"TV Channels"

Note that I use RVM and have done nothing special to have json working, must have been automatically installed.

3 Comments

json gem was probably installed as a dependency. To Rails, for example.
@Sergio Hi, I don't have Rails, but I love when things work well, without painful installation, as with RVM. I did a minimum install with Ruby 1.8.6, 1.9.2 and JRuby.
Well, I don't think RVM installs json for itself :) Some other gem must have required it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.