Loading objects with custom class names in EmberJS with Rails + active_model_serializers

I have several models in Rails that look something like this:

class Issue < ActiveRecord::Base belongs_to :reporter, class_name: 'User' belongs_to :assignee, class_name: 'User' has_many :comments end class User < ActiveRecord::Base end class Comment < ActiveRecord::Base end 

with such serializers:

 class IssueSerializer < ActiveModel::Serializer attributes :id embed :ids, include: true has_one :reporter, :embed => :ids has_one :assignee, :embed => :ids end class UserSerializer < ActiveModel::Serializer attributes :id, :name end class CommentSerializer < ActiveModel::Serializer attributes :id, :body end 

This creates JSON that looks something like this:

 { "issues": [ { "id": 6, "reporter_id": 1, "assignee_id": 2, "comment_ids": [ 3 ] }, ], "comments": [ { "id": 3 "body": "Great comment" } ], "reporters": [ { "id": 1 "name": "Ben Burton" } ], "assignees": [ { "id": 2 "name": "Jono Mallanyk" } ] } 

The problem is that side-loading JSON objects and JSON assignable objects are not recognized by Ember as User objects, and I see the following error:

 Uncaught Error: assertion failed: Your server returned a hash with the key reporters but you have no mapping for it 

I do not want to delete

 embed :ids, include: true 

from my IssueSerializer, because then the comments will not be serialized.

There are several possible solutions to this problem that I have considered:

  • If the embed method for ActiveModel :: Serializer accepts a list of models in the include option, this can filter the JSON response to include only side-loaded comments.
  • The Ember data model can be configured for users with side-loading from "users", "reporters" and "successors" ... but, as far as I can tell from the source, it only supports one key for sideloadAs.
  • Somehow ignoring / disabling side-loading errors for unknown keys (perhaps the least sensible approach).

Is there any other option that I'm missing here? I think that I may have to write a fix and send a transfer request to rails-api / active_model_serializers, emberjs / data, or both.

EDIT . My workaround for this is to change the IssueSerializer to only serialize identifiers for reporter and assignee:

 class IssueSerializer < ActiveModel::Serializer attributes :id, :reporter_id, :assignee_id embed :ids, include: true has_many :comments, :embed => :ids end 
+7
source share
3 answers

I had a similar problem and found a solution in ActiveModel :: Readme Serializers . You can use the :root option. Try something like this for a serializer release:

 class IssueSerializer < ActiveModel::Serializer attributes :id embed :ids, include: true has_one :reporter, :root => "users" has_one :assignee, :root => "users" has_many :comments end 
+4
source

You should read this page . Section 12 explains the issue of loading data of the same type:

Now it is expected that homeAddress and workAddress will be loaded together as addresses, because they are of the same type. In addition, default root file naming conventions (underscores and lowercase letters) will now also apply to loaded root names.

Your model should look like this:

 App.Issue = DS.Model.extend({ reporter: DS.belongsTo('App.User'), assignee: DS.belongsTo('App.User'), comments: DS.hasMany('App.Comment') }); 

The JSON result should have a key for users:

 { "issues": [ { "id": 6, "reporter_id": 1, "assignee_id": 2, "comment_ids": [ 3 ] }, ], "comments": [ { "id": 3 "body": "Great comment" } ], "users": [ { "id": 1 "name": "Ben Burton" },{ "id": 2 "name": "Jono Mallanyk" } ] } 

Since you configured in your model that the reporter is of type User , Ember looks for the user as a result.

+1
source

I had the same problem, adding include: false in the association helped.

  embed :ids, include: true attributes :id, :title has_many :domains, key: :domains, include: false has_many :sessions, key: :sessions 
0
source

All Articles