Active Model Serializers has_many associations
Asked Answered
D

1

7

I'm using the gem active_model_serializers.

Serializers:

class ProjectGroupSerializer < ActiveModel::Serializer
  attributes :id, :name, :description
  has_many :projects
end

class ProjectSerializer < ActiveModel::Serializer
  attributes :id, :name, :description
  belongs_to :project_group
end

Controller:

def index
  @project_groups = ProjectGroup.all.includes(:projects)
  render json: @project_groups, include: 'projects'
end

I'm getting the following response:

{
  "data": [
    {
      "id": "35",
      "type": "project_groups",
      "attributes": {
        "name": "sdsdf",
        "description": null
      },
      "relationships": {
        "projects": {
          "data": [
            {
              "id": "1",
              "type": "projects"
            },
            {
              "id": "2",
              "type": "projects"
            }
          ]
        }
      }
    }
  ],
  "included": [
    {
      "id": "1",
      "type": "projects",
      "attributes": {
        "name": "qweqwe",
        "description": null,
        "project_group_id": 1
      },
      "relationships": {
        "project_group": {
          "data": {
            "id": "1",
            "type": "project_groups"
          }
        }
      }
    },
    {
      "id": "2",
      "type": "projects",
      "attributes": {
        "name": "ewe",
        "description": null,
        "project_group_id": 2
      },
      "relationships": {
        "project_group": {
          "data": {
            "id": "2",
            "type": "project_groups"
          }
        }
      }
    }
  ]
}

I want to retrieve the associations inside the relationships object, not outside (in included array) as in the response that I'm receiving. Is it possible?

PS1: belongs_to associations works fine, the associations comes inside the relationships object, as in docs.

PS2: I want to do this because I have 3 or 4 associations and I want to access them from each object. This way that I'm getting the response will be a real mess.

Dignify answered 3/2, 2017 at 3:36 Comment(1)
Just as an aside: this would be invalid JSON:API, so it's not likely to be something easy to maintain/support. The relationships key is supposed to contain resource identifier objects. A JSON:API client should parse those for you if you keep them as valid JSON:API (But I agree it's a little cumbersome to parse if writing your own client)Oink
T
23

You can do this by defining projects manually like this.

class ProjectGroupSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :projects

  def projects
    object.projects.map do |project|
      ::ProjectSerializer.new(project).attributes
    end
  end

end

Turbinal answered 3/2, 2017 at 7:23 Comment(4)
Thanks @NarashimaReddy, I also noticed if I change the config to format :json, it also works.Dignify
Worked great for me. Is it not better to have things under a relationships object as seen in JSONAPI spec though?Doubler
I agree with @mycellius, records from association has to be presented in relationships section. Is anyone did this? I'm trying to make it work with Grape + AMS.Featheredge
I had been searching for applying custom serializer on associations and nothing seemed to work. This is a lifesaver. Much appreciated!Violante

© 2022 - 2024 — McMap. All rights reserved.