412

How to convert a ruby hash object to JSON? So I am trying this example below & it doesn't work?

I was looking at the RubyDoc and obviously Hash object doesn't have a to_json method. But I am reading on blogs that Rails supports active_record.to_json and also supports hash#to_json. I can understand ActiveRecord is a Rails object, but Hash is not native to Rails, it's a pure Ruby object. So in Rails you can do a hash.to_json, but not in pure Ruby??

car = {:make => "bmw", :year => "2003"}
car.to_json
1
  • beware though, if the object on which you call to_json is already json, you'll get a mess: { foo: "bar" }.to_json.to_json Commented Oct 21, 2022 at 0:48

4 Answers 4

657

One of the numerous niceties of Ruby is the possibility to extend existing classes with your own methods. That's called "class reopening" or monkey-patching (the meaning of the latter can vary, though).

So, take a look here:

car = {:make => "bmw", :year => "2003"}
# => {:make=>"bmw", :year=>"2003"}
car.to_json
# NoMethodError: undefined method `to_json' for {:make=>"bmw", :year=>"2003"}:Hash
#   from (irb):11
#   from /usr/bin/irb:12:in `<main>'
require 'json'
# => true
car.to_json
# => "{"make":"bmw","year":"2003"}"

As you can see, requiring json has magically brought method to_json to our Hash.

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

7 Comments

all i can say is wow :) also thanks a lot!! so basically i was able to extend the json class dynamically??
I tried the same thing with Ruby object and it does not work?? >> require 'json' => true >> class Person >> attr_accessor :fname, :lname >> end => nil >> p = Person.new => #<Person:0x101155f70> >> p.fname = "Bill" => "Bill" >> p.lname = "Shine" => "Shine" >> p.to_json => "\"#<Person:0x101155f70>\""
No, no, someone has to code how the object of an arbitrary class should be serialized to JSON. They did it for Hash and Array classes in json gem, but your class Person is just a plain Object. But you can inherit Hash instead. You can open a new question if you don't manage.
thanks. here's the new question, any help would be appreciated. Thanks. stackoverflow.com/questions/3226054/…
You're showing what looks to be IRB type output. I was trying to get hash#to_json to work for DateTime object. Thanks to this post I got it. But I did inspect with p date_json This is what I got for a true string "{\"year\":2013,\"mon\":7,\"mday\":16,\"hour\":13,\"min\":54,\"sec\":32,\"zone\":\"-05:00\",\"offset\":-18000}" so you may see that it is making the key symbols as strings and of course that data is unchanged. Thanks again. Sorry I'm so late though.
|
22
require 'json/ext' # to use the C based extension instead of json/pure

puts {hash: 123}.to_json

Comments

19

You can also use JSON.generate:

require 'json'

JSON.generate({ foo: "bar" })
=> "{\"foo\":\"bar\"}"

Or its alias, JSON.unparse:

require 'json'

JSON.unparse({ foo: "bar" })
=> "{\"foo\":\"bar\"}"

1 Comment

JSON.generate only allows objects or arrays to be converted to JSON syntax. to_json, however, accepts many Ruby classes even though it acts only as a method for serialization: 1.to_json # => "1". Docs here: ruby-doc.org/stdlib-2.6.3/libdoc/json/rdoc/JSON.html
19

Add the following line on the top of your file

require 'json'

Then you can use:

car = {:make => "bmw", :year => "2003"}
car.to_json

Alternatively, you can use:

JSON.generate({:make => "bmw", :year => "2003"})

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.