Rails Serialization (Active Model Serializer)

Wajeeh Ahsan
2 min readFeb 3, 2020

--

Ruby on Rails is a great choice for an API specifically because rendering JSON is as easy as render :json. However, out of the box, Rails serves up some pretty ugly data. The result of this is much messy.
Moreover if you want to deal with the associations you’ve already defined for your introduced models, it will become a cause of headache for you.
But luckily, Rails provides some gems to handle all this. Just install any of them, define what you want to get rendered, and all the headache is for the gem. Among multiple available options, we will go for Active Model Serializer.

Add this in your Gemfile

gem 'active_model_serializers'

and run bundle install.

Now, when the gem is installed, you need to run a command to generate your serializer. Suppose I want to generate a serializer for my Project model, I’ll run run this command in the terminal:

rails g serializer project

This will create a file named proejct_serializer.rb under the app/serializers directory. Move to the file and introduce the attributes you want to be include in serialization. Suppose I just want to add id and title attributes of project while serializing. I’ll put the following code inside the file:

class ProjectSerializer < ActiveModel::Serializer  attributes :id, :titleend

Now move to the project_controller.rb and look for, suppose, show action. When you done with finding the right project to show, you can render it using just the following line

render json: project

This will render your project which looks much pretty like this:

{  "project": {    "id": 10,    "title": "First Project"  }}

Now, suppose you want to list the author of the project too. For this, yyou need to create a serializer for your author (‘user’ in my case) model by running the following command and tell the serializer which attributes of user you want (I allowed user id and email to be listed).

rails g serializer user

Now its time to tell your project serializer to include its author (user) too. For this, add a line in your project_serializer so it look like this

class ProjectSerializer < ActiveModel::Serializer  attributes :id, :title  has_one :userend

Now if you hit your api again, the following JSON will be rendered as a result:

{   "project": {    "id": 10,     "title": "First Project",    "user": {      "id": 1,      "email": "wajeehahsan9@gmail.com"    }  }}

We’re DONE with serialization part but keep in mind these two things:

1- Serializers are only concerned with multiplicity, and not ownership. belongs_to ActiveRecord associations can be included using has_one in your serializer like we did for project_serializer. For has_many association, use has_many.

2- You can’t have two serializers that has_many / has_one each other. Like in our case, each project has_one user (to implement belongs_to association) but we didn’t introduced has_many :projects in our user_serializer though each user has_many projects in our schema. Otherwise it’ll cause stuck with an error like:

SystemStackError (stack level too deep)

Because project_serializer will start referring to user_serializer and user_serializer will refer back to project_serializer and it will stuck in an infinite loop.

--

--

Wajeeh Ahsan
Wajeeh Ahsan

No responses yet