Reputation: 12018
Using ember-data, I have this two models:
App.Post = DS.Model.extend
title: DS.attr "string"
body: DS.attr "string"
categories: DS.hasMany "App.Category"
App.Category = DS.Model.extend
name: DS.attr "string"
posts: DS.hasMany 'App.Post'
and this serialization:
class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :body
has_many :categories
embed :ids, include: true
end
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
end
When I ask for posts, I get the expected JSON and I can access a post's categories without problem, but if I request the categories (that I think that they are cached) I get the categories without any relation to posts. It doesn't even try to make a get request (that wouldn't work either).
So, shouldn't categories have their posts relations filled up?
Not sure if I miss something in ember or AMS (which I think that the category serializer should know that has many posts)
Upvotes: 1
Views: 542
Reputation: 12018
Well, after struggling with some guys at IRC I ended with this solution, which I hope it will be helpful for others and maybe improved.
The problem was that the categories doesn't had any post reference, So if you ask for Posts, you get the posts with categories, but the categories themselves knows nothing about posts.
If I try to do something like:
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
has_many :posts
embed :ids, include: true
end
it will explode because they are referencing each other and you get a "Too deep level" or something like that.
You can do something like:
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
has_many :posts, embed: :objects
end
and it will work, but the result JSON will be huge because when you request posts, you get every post + every comment and inside them, every post that have that category... No love
So what's the idea? Having something like:
class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :body
has_many :categories
embed :ids, include: true
end
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
has_many :posts, embed: :ids
end
For every post you get the categories_ids and for every category you reference, you only get its attributes and the ids (not the entire objects) of the posts that belongs to that category.
But what happens when you go to '/#/categories' and you didn't loaded the posts yet? Well, since your CategorySerializer doesn't serialize any post, you won't get anything.
So since you can't do cross references between serializers, I ended with 4 serializers. 2 for posts and their categories and 2 for categories and their posts (so, doesn't matter if you load the posts first or the categories):
class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :body
has_many :categories, serializer: CategoriesForPostSerializer
embed :ids, include: true
end
class CategoriesForPostSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :posts, embed: :ids
end
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
has_many :posts, serializer: PostsForCategorySerializer
embed :ids, include: true
end
class PostsForCategorySerializer < ActiveModel::Serializer
attributes :id, :title, :body
has_many :categories, embed: :ids
end
This does the trick. But since I'm new with Ember and I'm not a crack of JSON design. If someones knows a simple way or maybe doing some embedded (always or load in the adapter, which I don't understand yet), please comment :)
Upvotes: 2