Difference between as_json and to_json method in Ruby
to_json
returns String. as_json
returns Hash with String keys.
> { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
"{\"name\":\"Konata Izumi\",\"age\":16,\"1\":2}"
> { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.as_json
{"name"=>"Konata Izumi", "age"=>16, "1"=>2}
What is the difference between as_json vs JSON.parse?
The two methods are in some sense exact opposites of each other:
JSON.parse
parses a RubyString
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 onlyHash
,Array
,String
,Integer
,Float
,true
,false
, andnil
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 fromJSON.parse
.
Apart from operating in opposite directions, there are some minor other differences as well:
JSON.parse
is a concrete method, whereasas_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 thejson
gem, which is a default gem). Theas_json
protocol is defined byActiveRecord
'sSerializers
API, i.e. it is part ofActiveRecord
, 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 Hash
es.
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.)
How to override the 'as_json' or 'to_json' method in order to 'respond_to' without including specified information?
If it is only in one action you can try:
format.json { render :json => @account, :except => :password }
if you need it for more than one action than the override would be better:
# Exclude password info from json output.
def to_json(options={})
options[:except] ||= :password
super
end
the same is good for as_json
# Exclude password info from json output.
def as_json(options={})
options[:except] ||= :password
super
end
What is the difference between to_json VS JSON.parse() in Ruby?
They're opposite methods. to_json
converts the given object to a JSON string, while JSON.parse()
parses the given JSON string and converts it to an object:
json_string = {first_name: 'John', last_name: 'Doe'}.to_json
# => "{\"first_name\":\"John\",\"last_name\":\"Doe\"}"
json_object = JSON.parse(json_string)
# => {"first_name"=>"John", "last_name"=>"Doe"}
json_object['first_name']
# => "John"
Activerecord associations as JSON with Grape
You might want to use #as_json
instead.
So you can do
User.includes(:address).as_json(include: :address)
and that gives you a hash instead of a json string.
Have to_json return a mongoid as a string
You can monkey patch Moped::BSON::ObjectId
:
module Moped
module BSON
class ObjectId
def to_json(*)
to_s.to_json
end
def as_json(*)
to_s.as_json
end
end
end
end
to take care of the $oid
stuff and then Mongoid::Document
to convert _id
to id
:
module Mongoid
module Document
def serializable_hash(options = nil)
h = super(options)
h['id'] = h.delete('_id') if(h.has_key?('_id'))
h
end
end
end
That will make all of your Mongoid objects behave sensibly.
Saving hash as json and getting it back trouble in ruby on rails
I think passing the object itself with to_json conversion, is better for what you need and it will be saved as hash.
def getting_hash
video = Video.new
video.id = 12
video.title = "How to make it work?"
video.desc = "No idea..."
# Removing the hash conversion step
write_to_file(video)
end
Related Topics
How to Set a Request.Referrer Inside My Rspec
How to Set the Httponly Flag on a Cookie in Ruby on Rails
Bash: /Home/Xxx/.Rvm/Scripts/Rvm: No Such File or Directory
Document Model Attributes with Yard
Ruby Gems in Stand-Alone Ruby Scripts
Ruby on Rails User Registration Using Rest API Call and Devise
Rails 4 Update Nested Attributes
Checking If a String Is Valid JSON Before Trying to Parse It
Start Using Ruby on Rails, Web Services and Oauth
Begin Rescue Not Catching Error
Ruby Array to Hash: Each Element the Key and Derive Value from It
How to Stop God from Leaving Stale Resque Worker Processes
How to Implement Options Hashes in Ruby
Datetime with Mongodb/Mongoid and Rails 3 Not Populating
How to See the Ruby Code in a Proc