Rails API and Serializers: How to Send Better Data

Mdiouf
The Startup
Published in
5 min readAug 30, 2020

In rails, a serializer allows you to customize data instead of having a default render.

In this article, we’ll look at a step by step guide to using the serializer in your application.

The problem with the Rails API

Rails is a great way to be used as an API with the render json method. However, the JSON data is often full of things you don’t want and doesn’t offer many options for customization.

Let’s say you want to query a list of dogs and their owners from your database. We’ll define the two models and routes:

rails g model Person
rails g model Dog
Person and Dog models

Let’s define our routes and controllers

rails g controller Dogs 
rails g controller People

Now our PeopleController will look like this:

We seed our database with a list of people and dogs. In your seeds.rb file, you can have:

https://gist.github.com/MouhaDiouf/2b016d7a7e2a7c8753fade0dafbae3f0

Then run the command

rails db:seed

This command will help you seed your database with new data. That way, you can make API calls to retrieve them.

Now let’s define our routes :

These routes will help us query all the dogs in the database as well as the people.

Here are the two routes I am creating with the GET method:

GET http://localhost:3000/dogs 
GET http://localhost:3000/dogs/:id

We’ll be more interested in querying the dog's endpoint.

Querying data without a serializer

After defining our routes, controllers, and seeding our database, we can use the available routes to query a list of dogs.

To do that, we’ll use Postman. Postman is a software development tool that helps you make API calls and test them. If you haven’t already, I recommend you install it. Not only will it help you in this tutorial, but as well in your daily work.

Download Postman here

With Postman installed, let’s start our Rails server using the default port with the command:

rails server ou simply rails s

Next step, open Postman:

Postman interface

Let’s say you want to query a list of all the dogs available in the database, using the normal routes we previously said. With Postman, we can make a GET request to handle it. Make sure you start your Rails server and copy the routes into Postman (for a GET request)

The default data will give you :

[{"id": 1,"name": "Lisa","breed": "German shepherd","age": 3,"created_at": "2020-08-28T07:55:40.579Z","updated_at": "2020-08-28T07:55:40.579Z","person_id": 1},{"id": 2,"name": "Buddy","breed": "Labrador Retriever","age": 1,"created_at": "2020-08-28T07:55:40.602Z","updated_at": "2020-08-28T07:55:40.602Z","person_id": 1},{"id": 3,"name": "Rocky","breed": "Husky","age": 4,"created_at": "2020-08-28T07:55:40.625Z","updated_at": "2020-08-28T07:55:40.625Z","person_id": 1}]

In this case, we are getting a list of dogs with the name, breed, person_id, etc.

But do you need all this information? Is there anything else you would like to know about each of those dogs? For example, each dog has its owner. But in this data, we only get a “user_id”. Not that intuitive…

As well, I don’t need to know when data was created or updated. This includes some customization when the app renders. And you can do this with a serializer!

Using the serializer gem

The active_model_serializer gem allows you to customize the JSON file you render. Here’s the same JSON file as before, but with a serializer.

{"id": 1,"name": "Lisa","age": 3,"breed": "German shepherd",  "person": {    "id": 7,    "name": "John Doe"}

Do you see the difference? Now, we have an owner and removed the created_at and updated_at keys. Let’s see how we can do it step by step.

First, let’s install our serializer. For that, we use the gem active_model_serializer. So add this line in your gemfile.

gem ‘active_model_serializer’

In your Rails app, run:

bundle install 

Creating your first serializer

The next step is to create a serializer for a model you want to query data from. Let’s follow our example and decide to serialize our Dog model.

In your terminal, run:

rails generate serializer Dog

This command creates a new folder called serializers (in your ‘app’ folder) and a new file called dog_serializer.rb like this:

Dog serializer file

The default attribute is :id . This means when we make a new call to our dog index endpoint, the serializer will take care of the render and return what is in the attributes (hence only id here)

If we make a new request, we get:

[{"id": 1},{"id": 2},{"id": 3}]

That’s it! Now we are taking control of the rendering of our JSON file! We can add as many elements to our attributes and it will show in our rendering.

Let’s say we want to only show the id, name, breed, and age of the dog. We can add all these attributes to our serializer:

Dog serializer with custom attributes
[{"id": 1,"name": "Lisa","age": 3,"breed": "German shepherd"},{"id": 2,"name": "Buddy","age": 1,"breed": "Labrador Retriever"},{"id": 3,"name": "Rocky","age": 4,"breed": "Husky"}]

And you can put(or omit) whatever attribute of dog you want to render. This includes as well as pictures or the owner of each dog. Let’s see now how we can render the owner for each dog:

For that, we’ll add the following line to the DogsSerializer class:

belongs_to: :person

This line adds the owner (person) while rendering the data like this:

[{"id": 1,"name": "Lisa","age": 3,"breed": "German shepherd",  "person": {    "id": 7,    "name": "John Doe",    "age": 36,    "created_at": "2020-08-29T16:54:32.605Z",    "updated_at": "2020-08-29T16:54:32.605Z"    },
... Rest of data ...
]

You can even customize the “person” data by creating a serializer for the Person model:

rails g serializer person

Then in person_serializer.rb :

person_serializer.rb file

This returns our customized data with only the name and id of that person:

[{"id": 1,"name": "Lisa","age": 3,"breed": "German shepherd","person": {"id": 7,"name": "John Doe",},
... Rest of data ...
]

That’s it! Now you understand how to use a serializer in Ruby on Rails.

Using serializer is a great way to customize the data you render. Not only this, but you can also attach a picture(link) associated with the model and send its link in your JSON file as well. In this case, you’ll need to use Active Storage.

--

--

Mdiouf
The Startup

I am a full-stack developer with a passion for technology and learning new things. Founder of JavaScriptLearned.