DEV Community

Kevin Sassé
Kevin Sassé

Posted on

Ruby on Rails Serialization: The Basics

Rails is a powerful Ruby framework that allows developers to focus on developing while handling most of the tedium work, i.e. database querying, in the background as long as you, the developer, follow the "convention-over-configuration" format. Rails' generators make following that format even easier.

For my current project, we want a User to be able to see all of their upcoming events. There a few ways to accomplish this and luckily Rails offers a couple simple solutions to us.

Note: Rails' conventions rely on the resource associations, In my previous blog I cover Active Record associations and some tips to help set them up correctly.

USING INCLUDE: & EXCEPT:

When we query the database to find a User, we want to receive the User's information along with the events associated with that User. By default, the show action in the Users Controller will only return the User data:

#users_controller.rb
    def show
        user = User.find(params[:id])
        render json: user
    end

---

#server response
{
    "id": 2,
    "user": "kevin"
    "created_at": "2022-12-08T07:03:38.943Z",
    "updated_at": "2022-12-08T07:03:38.943Z",
}
Enter fullscreen mode Exit fullscreen mode

If we add include: :events as part of the show action's render we will receive all events associated with that user.

#users_controller.rb

    def show
        user = User.find(params[:id])
        render json: user, include: :events
    end

---

#server response
{
    "id": 2,
    "user": "kevin",
    "created_at": "2022-12-08T07:03:38.943Z",
    "updated_at": "2022-12-08T07:03:38.943Z",
    "events": [
         {
            "id": 9,
            "name": "Muse",
            "venue": "Houston Center",
            "event_type": "concert",
            "created_at": "2022-12-08T06:09:39.617Z",
            "updated_at": "2022-12-08T06:09:39.617Z"
        },
        {
            "id": 5,
            "name": "Radiohead",
            "venue": "Atlanta-Center",
            "event_type": "concert",
            "created_at": "2022-12-08T06:09:39.596Z",
            "updated_at": "2022-12-08T06:09:39.596Z"
        }
    ]
}

Enter fullscreen mode Exit fullscreen mode

Rails generators will, by default, add t.timestamps columns to your tables. We can use except: to prevent them from being returned by the server, however this will only exclude those keys from the top level resource, our events will still show those key/value pairs.

#users_controller.rb

    def show
        user = User.find(params[:id])
        render json: user, except: [:created_at, :updated_at], include: :events
    end

---

#server response
{
    "id": 2,
    "user": "kevin",
    "events": [
         {
            "id": 9,
            "name": "Muse",
            "venue": "Houston Center",
            "event_type": "concert",
            "created_at": "2022-12-08T06:09:39.617Z",
            "updated_at": "2022-12-08T06:09:39.617Z"
        },
        {
            "id": 5,
            "name": "Radiohead",
            "venue": "Atlanta-Center",
            "event_type": "concert",
            "created_at": "2022-12-08T06:09:39.596Z",
            "updated_at": "2022-12-08T06:09:39.596Z"
        }
    ]
}

Enter fullscreen mode Exit fullscreen mode

We could work around that by nesting include: and except: statements, however, even with this simple example, that becomes very messy:

    def show
        user = User.find(params[:id])
        render json: user.to_json(except: [:created_at, :updated_at], include: [:events => {except:[:created_at, :updated_at]}])
    end

---

#server response
{
    "id": 2,
    "user": "kevin",
    "events": [
         {
            "id": 9,
            "name": "Muse",
            "venue": "Houston Center",
            "event_type": "concert",
        },
        {
            "id": 5,
            "name": "Radiohead",
            "venue": "Atlanta-Center",
            "event_type": "concert",
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

If you really wanted to, you can keep chaining include: and except: as much as needed but Rails provides a better way.

SERIALIZERS

Using Rails serializers allows us to clean up the Users Controller and control what data is being returned by the server. You will have to make sure the gem is added to your Gemfile and installed. This gem is not included when running rails new

gem 'active_model_serializers'

Once installed, you can use rails g resource to create a model, controller and serializer at the same time, or you can also use rails g serializer <name(singular)> if you already have a model & controller.

Serialzers user attributes to define what keys are returned instead of only: or except:. They also make use of Active Record associations to include data from other tables.

Returning to our User events example, we can simplify the Users Controller and add attributes and the necessary relationships to our serializers.

#users_controller.rb
    def show
        user = User.find(params[:id])
        render json: user
    end

---

#user_serializer.rb
  class UserSerializer < ActiveModel::Serializer
    attributes :id, :username
    has_many :events
  end

---

#event_serializer.rb
  class EventSerializer < ActiveModel::Serializer
    attributes :id, :name, :venue, :event_type
  end

Enter fullscreen mode Exit fullscreen mode

After updating all the files, our server response will be:

#server response
{
    "id": 2,
    "user": "kevin",
    "events": [
         {
            "id": 9,
            "name": "Muse",
            "venue": "Houston Center",
            "event_type": "concert",
        },
        {
            "id": 5,
            "name": "Radiohead",
            "venue": "Atlanta-Center",
            "event_type": "concert",
        }
    ]
}

Enter fullscreen mode Exit fullscreen mode

Using serializers we can make our code cleaner and more efficient by following "separation of concerns" and Rails "convention over configuration". This is a simple example showing the basics of Rails Active Model Serializers

Further reading:
Active Model Serializers Github

Top comments (0)