I am trying to use custom serializers in my relationship, and they seem to work with the custom adapter, however, when I specify the json_api adapter in an initializer, they stop to work.
Here is my 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
When I use the json_api adapter the relationships return empty data sets (just id and type attributes), when I use the default adapter everything works fine. Is that a bug or am I not getting something ?
EDIT: SO question: http://stackoverflow.com/questions/32036253/active-model-serializer-not-working-with-json-api-adapter
Hey @thecritic,
It is works fine for me. 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.
This adapter follows 1.0 of the format specified in
jsonapi.org/format. It will include the associated
resources in the"included"member when the resource names are included in the
includeoption.render @posts, include: ['authors', 'comments'] # or render @posts, include: 'authors,comments'
Ex.
def show
render json: @post, include: 'comments'
end
and then, 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"
}
}
]
}
Let us know if it works for you as well. :smile:
@thecritic it's as @bacarini just said, you may also include chained associations by using:
render @posts, include: ['authors.profile', 'comments']
@bacarini could you please add the same response to the SO question? :smile: It might be easier for other to find as well.
Hi @bacarini!
First of all, thanks for your reply. Yes I knew about includes and I went this route and it does make sense when I think about it (one wouldn't want to always include the fully fleshed out objects in the response data without explicitly specifying includes...), but isn't there a way to specify that these objects should be fully fleshed out within the relationships ? Or is this expected behavior ? But isn't it kind of overkill if you had both resource identifier objects and includes in there ? There is kind of a redundancy issue there, no ?
So @thecritic, this is the expected behavior, because it follows the json-api conventions, as you can see by the chain bellow, it does not support an attributes key.
- relationships: a relationships object describing relationships between the resource and other JSON API resources.
A relationship object MUST contain at least one of the following:
...
- data: resource linkage
Resource linkage MUST be represented as one of the following:
...
- A "resource identifier object" MUST contain
typeandidmembers.
I know it might seems an overkill, but the idea is to force you to keep it simple. I honestly don't think it's an overkill if you need it, because the id and type on the relationships represents simplest image of the object you are retrieving and it's associations.
@joaomdmoura I could imagine that you could infer the relationship objects from the includes ? I thought that the set of includes overlaps with the relationship objects, which is where the redundancy comes in. Well I guess there is a good reason for doing it this way, so not going to further question this approach. Thanks @joaomdmoura and @bacarini for pointing me into the right direction and solving my problems! Much appreciated!
We do not infer the relationship from the includes because you can also include other objects that are not related to the original object, as in:
render @posts, include: ['authors.profile']
I think this is a suitable question but more related to json-api itself, they have a pretty active project and are really friendly in case you want to open an issue there to question about it :smile: https://github.com/json-api/json-api
:+1: :smiley:
@joaomdmoura @bacarini I now fully understand what's happening there (Re-read the JSON 1.0 Format, now it's clear why it is the way it is... ), however do I understand correctly that I have to aggregate the data myself ? So, with the "conventional" JSON format I could just access the relationships, for example post.post_sections would be an array and I could just simply iterate over it. With the 1.0 format I would have to implement some logic -- which inevitably creates overhead on the client -- myself to aggregate the data so that I can use it like the old format, i.e. go through the relationships first, find the includes by type and id and flesh them out myself before using them ? That seems kind of complicated... Is that the case ?
I'm not sure I got it, but you could use other adapter than the json_api, like the usual flatten_json or the json one, this would not follow json-api conventions but would work really well.
Most helpful comment
Hey @thecritic,
It is works fine for me. Relationships only returns
idandtypeaccording to json-api exmaples. If you need to return more information about this relation you should addincludeoption on your render action.Ex.
and then, output:
Let us know if it works for you as well. :smile: