How to Serialize Your Rails Backend
What is serialization?
The main idea: the process of organizing, or re-organizing, data to suit your needs
- It will make your life easier when building the frontend
- It keeps your code DRY! (Don’t Repeat Yourself) Instead of writing the same code 5 different times in each Controller action, write it once in your Serializer
- Reduces the number of fetch requests needed
- Allows you to nest resources more easily
One of my favorite aspects of programming is that there are infinite ways to accomplish any goal. With that in mind, I’m going to walk through how I used
ActiveModel::Serializer to organize data for my Rails backend.
Before we get started, take a few moments to think about these four models and their relationships.
1. Create your app from the terminal.
rails new my-app-backend --api --database=postgresql
I am using a Postgres database so I can later deploy my application on Heroku. While Postgres is not required here,
--api is. This tells Rails that your
ApplicationController should inherit from
ActionController::API instead of the usual
ActionController::Base. It also lets Rails know you don’t need to create Views, just Models and Controllers.
Note: when using Postgres, you will have to open the Postgres app, ensure a server is running, then run
rails db:create in your terminal before you can run any migrations. Once the Postgres server is running, it will display any tables previously created. As long as you leave the Postgres server running in the background, you can now minimize its window. No further actions will be required.
ActiveModel::Serializer to your Gemfile and run
bundle install in your terminal.
gem 'active_model_serializers', '~> 0.10.0'
3. Create models, controllers, routes, and serializers all at once by running
rails g resource in your terminal:
rails g resource User email first_name last_name avatar
This will create the following files:
as well as
resources :users in
Create resources for the rest of your models:
rails g resource Project title subtitle user_id:integerrails g resource Prompt content img prompt_type project_id:integerrails g resource Answer prompt_id:integer content correct:boolean
After checking that your schemas are correct, run
rails:db:migrate and add relationships to your models
4. Seed your database with some fake data! I created 1 user with 2 projects. Each project had 10 prompts. Each prompt had 4 answers (1 correct, 3 incorrect).
5. Set up Controllers. To ensure I could play around with my data structure from any route, I wrote
show actions for all of my models. I won’t actually need both for every model, but I can go back and delete them later. In the planning stages, it’s better to have something and not need it, than to need it and not have it.
Start up your server!
Here is a screenshot of each index page currently:
This is great, and definitely better than the structure we get without serializers, which would include all of our
However, this will still require us to make 4 seperate fetches just to get all the data related to a single project.
6. Decide how you want your data to be structured. This is the most difficult part of the process. Think about when you will make your fetches from your front end. What models should be grouped together to reduce the number of fetches needed?
To start I added relationships to my Serializers.
Like magic, we can now see all of our related data nested in each index!
7. Make it your own! For this specific app, I want my data to fit a very specific structure. Let’s go through our
I want to be able to see a user’s projects, but currently it is showing me the
user_id within each project, even though it’s nested within a
user object. Adding relationships to the
Serializers results in Rails calling on the
ProjectSerializer from within the
UserSerializer. To avoid this default behavior, I’m going to comment out my relationships for now and write custom attributes. Just like any Ruby class, we can write
instance methods! I’m going to write one called
projects. I can then add
:projects as an attribute of my
When I go to a
User show page now, I should see a key of
projects with an array of that user’s projects. Each
Project should only have keys for its’
id, title, and
instance methods can be written to show anything, not just related models.
For example, let’s add something random to our
So, make your API your own! Happy Coding!
If you would like to see how I chose to serialize the rest of my data, check out the screenshots below.