Home > Blockchain >  What is the difference between as_json vs JSON.parse?
What is the difference between as_json vs JSON.parse?

Time:07-25

Could someone please specify difference between as_json and JSON.parse?
The only difference is that JSON.parse part of Ruby Standard Library and as_json part of Rails ActiveSupport?

Rails console:

irb(main):001:0> json_str = "{\"foo\": {\"bar\": 1, \"baz\": 2}, \"bat\": [0, 1, 2]}"
irb(main):002:0> puts JSON.parse(json_str)
{"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}
irb(main):003:0> puts json_str.as_json
{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}

Ref:

CodePudding user response:

The two methods are in some sense exact opposites of each other:

  • JSON.parse parses a Ruby String containing a JSON Document into a Ruby object corresponding to the JSON Value described by the JSON document. So, it goes from JSON to Ruby.
  • as_json returns a simplified representation of a complex Ruby object that uses only Ruby types that can be easily represented as JSON Values. In other words, it turns an arbitrarily complex Ruby object into a Ruby object that uses only Hash, Array, String, Integer, Float, true, false, and nil which correspond to the JSON types object (really a dictionary), array, string, number, boolean, and null. The intent is that you can then easily serialize this simplified representation to JSON. So, as_json goes from Ruby (halfway) to JSON. In other words, the opposite direction from JSON.parse.

Apart from operating in opposite directions, there are some minor other differences as well:

  • JSON.parse is a concrete method, whereas as_json is an abstract protocol that is implemented by many different kinds of objects. (Similar to e.g. each in Ruby).
  • JSON.parse is part of the Ruby standard library (but not the core library, more precisely, it is part of the json gem, which is a default gem). The as_json protocol is defined by ActiveRecord's Serializers API, i.e. it is part of ActiveRecord, not Ruby.

So, why does as_json exist in the first place? Why this two-step process of converting complex Ruby objects to simpler Ruby objects and then to a JSON Document instead of going straight from complex Ruby objects to a JSON Document? Well, if you have complex Ruby objects, chances are, that no object actually fully knows how to serialize itself as a JSON Document. It has to first ask its constituent objects to serialize themselves, and then stitch it all together, and this applies recursively to the constituent objects as well. With all this stitching together of JSON Documents, there is a real risk of producing an invalid JSON Document or double-encoding some part of it, or something along that lines.

Basically, once you have serialized something to a JSON Document, then all you have is a String and all you can do is String manipulation. Whereas, if you have a richer Ruby object like Hash, Array, Integer, etc., then you can use that object's methods as well. Imagine, for example, having to merge two JSON Documents containing JSON Objects as a String compared to simply merging two Ruby Hashes.

So, the idea is to use as_json first to create a Ruby object that is simpler and less powerful than the original, but still much more powerful than a simple String. And only once you have assembled the entire thing, do you use to_json to serialize it to a JSON Document. (Or rather, the serialization framework does that for you.)

CodePudding user response:

JSON.parse parses a json string into a ruby hash (only accepts a string as an argument).

.as_json is a serialization method available to all data types, not just strings.

E.g. from the docs:

user = User.find(1)
user.as_json
# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
#     "created_at" => "2006-08-01T17:27:133.000Z", "awesome" => true}

But JSON.parse won't handle that:

user = User.find(1)
JSON.parse(user)
--> no implicit conversion of User into String (TypeError)

CodePudding user response:

JSON.parse() parses the given JSON string and converts it to an Object,While the as_json Returns a hash representing the model.

user = User.first
user.as_json

=> {"id"=>1, "email"=>"[email protected]", 
"name"=>"Noman", "user_type"=>"Manager"}

and if we apply as_json to string it simple return that string

json_str = "{\"foo\": {\"bar\": 1, \"baz\": 2}, \"bat\": [0, 1, 2]}"
json_str.as_json

=> "{\"foo\": {\"bar\": 1, \"baz\": 2}, \"bat\": [0, 1, 2]}"

if we apply JSON.parse() to string it returns hash.

JSON.parse(json_str)
=> {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}
  • Related