norbas
norbas

Reputation: 89

Add "namespace" to serializer

I have User model existing in my db, however I would like to return json response with active_model_serializers gem in which user attributes are encapsulated/nested in player namespace which DOES NOT exist in db (say it is virtual and this is arbitrary expected response).

Instead of:

{
    "email": "[email protected]",
    "first_name": "Hey",
    "last_name": "Hoo",
    "birthdate": "1540-05-05",
    "phone_number": "856539571"
}

I would like to have:

{
    "player":
    {
        "email": "[email protected]",
        "first_name": "Hey",
        "last_name": "Hoo",
        "birthdate": "1540-05-05",
        "phone_number": "856539571"
    }
}

Upvotes: 1

Views: 655

Answers (3)

norbas
norbas

Reputation: 89

Answer provided before works as well, but in the end I used slightly different approach. Turned out that aside player there should be another json, let's say team, which makes final response look like this:

{
    "player": 
    {
        "email": "[email protected]",
        ...
    },
    "team":
    {
        "name": "Fancy Team",
        ...
    }
}

What I actually did was to define exact json that I wanted to use, like this:

class UserSerializer < ActiveRecord::Serializer
    attributes :player
    attributes :team

    def player
        {
            email: object.email,
            ...
        }
    end

    def team
        { 
            name: object.name,
            ...
        }
    end
end

If I used root option in render json:, whole serializer would be encapsulated in this name. Sorry for not clearing it at the beginning.

Upvotes: 0

Roman Alekseiev
Roman Alekseiev

Reputation: 1920

When Nwocha's answer is correct I will add more details to it.

As for documentation says:

Overriding the resource root only applies when using the JSON adapter.

Normally, the resource root is derived from the class name of the resource being serialized. e.g. UserPostSerializer.new(UserPost.new) will be serialized with the root user_post or user_posts according the adapter collection pluralization rules.

When using the JSON adapter in your initializer (ActiveModelSerializers.config.adapter = :json), or passing in the adapter in your render call, you can specify the root by passing it as an argument to render. For example:

  render json: @user_post, root: "admin_post", adapter: :json

This will be rendered as:


  {
    "admin_post": {
      "title": "how to do open source"
    }
  }

Note: the Attributes adapter (default) does not include a resource root. You also will not be able to create a single top-level root if you are using the :json_api adapter.

Upvotes: 2

Adim
Adim

Reputation: 1776

Within the UserSerializer class, define the root attribute. E.g:

class UserSerializer < ActiveModel::Serializer
  root :player

  ...
end

Upvotes: 1

Related Questions