Search code examples
ruby-on-railsrubyjsonactive-model-serializers

Active Model Serializer not working with json_api adapter


I am trying to use custom serializers for the relationships in a serializer and the json_api adapter enabled. However the relationships are not serialized correctly (or, better, not at all displayed/serialized).

PostController.rb

def index
  render json: Post.all, each_serializer: Serializers::PostSerializer
end

Serializer

module Api
  module V1
    module Serializers
      class PostSerializer < ActiveModel::Serializer
        attributes :title, :id

        belongs_to :author, serializer: UserSerializer
        has_many :post_sections, serializer: PostSectionSerializer
      end
    end
  end
end

JSON output:

{
    "data": [
        {
            "attributes": {
                "title": "Test Title"
            },
            "id": "1",
            "relationships": {
                "author": {
                    "data": {
                        "id": "1",
                        "type": "users"
                    }
                },
                "post_sections": {
                    "data": [
                        {
                            "id": "1",
                            "type": "post_sections"
                        }
                    ]
                }
            },
            "type": "posts"
        }
    ]
}

As you can see, the relationships are not fulfilled, which happens only if I specify a custom serializer for the relationships!!

If I do something like this:

module Api
  module V1
    module Serializers
      class PostSerializer < ActiveModel::Serializer
        attributes :title, :id

        belongs_to :author # no custom serializer!
        has_many :post_sections # no custom serializer!
      end
    end
  end
end

The relationships are shown correctly, but not using a custom serializer... What's the issue here ?

EDIT

According to the json API 1.0 Format, what I am getting back is the so-called resource identifier object.

The following primary data is a single resource identifier object that references the same resource:

{ "data": { "type": "articles", "id": "1" } }

Is there a way to prevent getting resource identifier objects, and get the actual data instead ?


Solution

  • Relationships only returns id and type according to json-api exmaples. If you need to return more information about this relation you should add include option on your render action.

    Ex.

    PostController.rb

    class PostsController < ApplicationController
      def show
        render json: @post, include: 'comments'
      end
    end
    

    Serializers

    class PostSerializer < ActiveModel::Serializer
      attributes :id, :title, :content
      has_many :comment, serializer: CommentSerializer
    end
    
    class CommentSerializer < ActiveModel::Serializer
      attributes :id, :title, :content
    end
    

    JSON output:

    {
        "data": {
            "id": "1",
            "type": "post",
            "attributes": {
                "title": "bla",
                "content": "bla"
            },
            "relationships": {
                "comment": {
                    "data": [
                        {
                            "type": "comments",
                            "id": "1"
                        }
                    ]
                }
            }
        },
        "included": {
            {
                "id": "1",
                "type": "comments",
                "attributes": {
                    "title": "test",
                    "content": "test"
                }
            }
        ]
    }