DEV Community

Swislok-Dev
Swislok-Dev

Posted on

Overriding Serializer

Setup the default serializers

While using Active Model Serializer in a Rails backend, to override the default serializer is to create a new serializer.

With a User model and Recipe model, we can select the information that gets displayed to simplify the JSON output.

# Serializer for User
class UserSerializer < ActiveModel::Serializer
  attributes :id, :username
  has_many :recipes
end

# Serializer for Recipe
class RecipeSerializer < ActiveModel::Serializer
  attributes :id, :name, :ingredients, :instructions
  belongs_to :user
end

Enter fullscreen mode Exit fullscreen mode

users#index

On users#index the output will show the user id and username along with all attributes of each recipe a user created. In this case recipe id, name, ingredients, and instructions will all be displayed.

To change the output for readability we'll add a few things.

# User serializer
class UserSerializer < ActiveModel::Serializer
  attributes :id, :username
  has_many :recipes, serializer: UserRecipeSerializer
end

# UserRecipeSerializer
class UserRecipeSerializer < ActiveModel::Serializer
  attributes :id, :name
end
Enter fullscreen mode Exit fullscreen mode

Now only the attributes from Recipe will be displayed that the UserRecipeSerializer has specified.

The downside is on user#show this serializer will also be used and will not show the full details of the recipe(s) if that was desired.

users#show

On the users#show route the controller action will have an extra bit to yet another serializer just for the purpose of showing full recipe details.

# UsersController
...

def show
  user = User.find_by_id(params[:id])
  if user
    # BEFORE SERIALIZER
    # render json: user

    #  AFTER SERIALIZER
    render json: { user: UserShowSerializer.new(user)}
  end
end

# UserShowSerializer 
class UserShowSerializer < ActiveModel::Serializer
  attributes :id, :username
  has_many :recipes
end
Enter fullscreen mode Exit fullscreen mode

The safest way to show the correct serializer would be to add in a .new method for each render call (not necessary) on the controller action to ensure the information needed will be displayed

Top comments (0)