Jul 082014
 

If you haven’t worked with JSON endpoints and/or Active Model Serializer much there’s some specific nuances to keep in mind when adding rails-api/active_model_serializers to your project.

In the old days, our JSON output typically looked like this:

[
 { “title”: “Post 1”, “body”: “Hello!” },
 { “title”: “Post 2”, “body”: “Goodbye!” }
]

You will note this is an array of “posts,” but you don’t explicitly know it is an array of posts because it just looks like a Javascript object (hence Javascript object notation, or JSON)

These days, it is more common to include what we call the “root element” in the json output. This is required on some more modern front-end frameworks, like Ember, and there are several reasons why including the root element is a good idea. (In Ember, in particular, you can side-load data along with the root element which is more efficient. Read more about side-loading ember data)

So a JSON endpoint that responds with the root element might look like this:

{
 “posts”:
  [
   { “title”: “Post 1”, “body”: “Hello!” },
   { “title”: “Post 2”, “body”: “Goodbye!” }
  ]
}

In an older Rails app (Rails 3 or prior), if you aren’t using Active Model serializer you are probably calling to_json yourself. (You are calling it implicitly if you do render json: @something in a controller.). The default behavior is to not include the root in your JSON output. (You can modify this globally with the ActiveRecord::Base.include_root_in_json, or other ways on a per-model basis).

This is a relatively long blog post to explain & document something simple, but important, that happens when you go to add the active_model_serializers gem to a project that doesn’t already have it: The default behavior of to_json – even when you aren’t explicitly using an ActiveModel::Serializer – is changed to include the root

If you read the section about including the root in the output of the ActiveModel Serializer., you’ll see much discussion about how to disable the default behavior. What it doesn’t say is that just adding the gem changes the default behavior of Rails 3, so if you have legacy code serializing JSON output, adding the gem will unintentionally change the behavior of your endpoints.