Recently we have been working on Rails API. During that time, we were curious about the difference between as_json and to_json. In this article, we are sharing the difference we learned.

to_json in Rails API

Let’s discuss how we started out building our APIs using ‘to_json’. to_json will return JSON string representing the hash. Option are passed to each element.

In to_json without any option,  the returned JSON string will include all the model attributes

to_json had some great options of ActiveRecord objects. We could just tell the method to only render certain attributes, or to include association or method calls. We had:

  • only – Only show column names in the output as specified in the list
  • except – Show all column names except the ones specified in the list

to_json works fine and seamlessly ok, as long as the database schema is deeply coupled with the API output.When it takes the next level where we want to render a certain attribute in json it start to break.

This will start to generate a bit load to controllers. Such methods of generating json don’t feel quite right and begin to break down. This is because the to_json is interested in ‘serializing’ a database object while most of the developers try to put relevant representation for their API.

Anytime to_json is called on an object, as_json is invoked to create the data structure, and then that hash is encoded as a JSON string using ActiveSupport::json.encode. This happens for all types: Object, Numeric, Data, String etc.

Now the creation of the json is separated from the rendering of the json.  as_json is used to create the structure of the json as a Hash, and the rendering of that hash into JSON string is left up-to ActiveSupport::json.encode.

as_json in Rails API

as_json Returns a hash representing the model. Like in to_json, option are passed to each element in as_json. The option include_root_in_json controls the top-level behavior of as_json. If true, as_json will emit a single root node named after the object’s type. The default value for include_root_in_json option is false. This behavior can also be achieved by setting the :root  option to true.

In as_json without any option, the returned HASH will include all the model attributes

The :only and :except options can be used to limit the attributes included, and work similar to the attributes method.

Default as_json will create a hash which includes all the model attributes. We normally override the as_json to create custom JSON structure.

As we were going through this we also came across a method called from_json. So we decided to write about it as well

from_json in Rails API

from_json will sets the model attributes from a JSON string. The default value for include_root option is false. We can change it to ‘true’ if the given JSON string includes a single root node.

Do not call to_json directly, and let the render take it, in controllers. Incase of custom structured or multi level JSON structure override as_json in the model or call as_json. Using as_json will help to worry one less.

References