Custom Serializers in Ruby on Rails

Gabriel Kutik
4 min readJul 12, 2020

During my on campus tutelage at the Flatiron bootcamp, we were taught the utility of using the Active Model Serializer, in order to pull out all the data you needed in one nested fetch. Although you had to now had to structure your database relations in a linear fashion (Grandparents -> Parents -> Children) rather than as a joiner (Grandparents -> Parents <- Children), using Active Model Serializer gave you the opportunity to pull your information out in one fell swoop, nesting the response data as you please.

I was given fair warning at the time that Active Model Serializer was being “soft deprecated”, but I did not understand the significance at the time. One day I woke up, and all my projects using Active Model Serializer in the back end no longer worked. Yipes!

New features, updates, and deprecation happen all the time. In a fast paced field, one must stay two steps ahead. The only thing permanent is change. It is not enough to tread water and stay afloat if the tides are pulling you away from the shore; one must swim against the current towards the Isle of Constant Improvement.

I was left with two options: learn another often used serializer “Fast JSON API”, or learn how to make my own customer serializers. The advantage of Fast JSON API is that it easy to implement, but you lose control of the format of your response data is nested. The advantage of customer serializers is your have more flexibility on how your data comes back, but it is a wee bit trickier to implement. My decision was to learn learn both, and not limit my horizons. Below I will show a rudimentary example of how one can make a customer serializer in Rails, using a crowdsourced online dictionary as an example. Better still, we can use a joiner model previously not available in Active Model Serializer. The relationship is as follows: Users -> Definitions <-Words.

After setting up the backend with their many to many relations, and insuring that Definitions had the User’s and Word’s foreign keys, it was time to create a customer serializer for the Definition class, and reorganize the structure for the DefinitionsController.

The first step is to find the folder called “app” in the top most level, and create a folder called “services”. Then create a file name after the model that ends with “_serializer.rb”. Remember, models are singular, controllers are plural, so my file was named “definition_serializer.rb”

In that file create a class called DefinitionSerializer. Create a method that will initialize the class passing an argument of the definition object. Set the instance to the object passed in. Next create a helper method that will return the object as JSON, and here you can customize which information one only want to be included. One can even limit the information passed by the top most level using :except. In this case, with one fetch to the Definition table the user_id and word_id come along free as foreign keys, but with the syntax set up in the serializer below I am able to pull out the user’s name, and the word’s spelling. I use :except to limit superfluous information from the Definition itself that is not needed, in this case the last time it was updated.

The next step is to have our DefinitionsController find the pass the instance or instances through an invocation of the serializer, and to structure our data as specified in our helper method.

With the addition of our custom serializer, and the tweaks to our controller, we should be able to get all the data we specified in one fetch. Let’s see if it worked.

Great! We get a response of an array of ten object. Now make sure the data came back in the way we specified.

This is exactly what we wanted. We have our foreign keys, but in addition , in only one fetch we were able to pull out the name of the person who created each definition, and we were also able to pull out the spelling out the word the definition was associated with. This was a major time saver by eliminating other fetches to the database, but also writing the logic that would then compare the Definition’s foreign key to the primary key of the corresponding User or Word.

--

--

No responses yet