1
votes

I have 3 models in a hasMany chain. E.G. Gallery -> Image -> Comment

Returning both the selected Gallery and the Images in it in a single json response works as expected. The backend is a Rails app using active_model_serializers, btw.

{"images":[...],"galleries":{"id":1,...,"images":[1,2,3]}}

But when I tell the serializer about the Comments and they get included in the json I get a mapping error from Ember.

{"comments":[...],"images":[...],"galleries":{"id":1,...,"images":[1,2,3]}}

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

I can't figure out how to properly tell Ember how to handle this. My debugging suggests that Anything in the json response has to be directly referenced in the Gallery model. I have tried adding a "mapping" to the RESTAdapter using both the singular and plural forms just to be sure. "comments: App.Comment" or "comment: App.Comment" makes no difference I can see.

I suppose I could give up and just do a few more requests but since the Comments are always used when a given Image is used, it feels wrong. I'd love some help figuring our how to allow the data in a single response.

Do I need to completely re-configure the serializers and Ember to embed the data instead of referencing them with IDs?

chers, Martin

(Note: The model names are fictive to make them more generally understandable compared to the fun domain I am actually modeling)

1
In my app, I'm doing something like Store = DS.Store.extend({ adapter: DS.RESTAdapter.create({ serializer: DS.RESTSerializer, bulkCommit: false, mappings: { action_words: ActionWord } }) }) and it works :ssly7_7
What I have done so far is to change the json to make the comments embedded in the images. It keeps the network chatter down but is less normalised than I'd like.Martin Westin
did you find a solution to your problem? I have the same problem, Ember is very strict on the format of the json expected and I can't get to change my back-end (Symfony) so easily...George Katsanos

1 Answers

2
votes

Thanks for prodding me to get back to this.

Here is what I have currently. I don't know if I can remove any of this as of the recent updates to Ember and Ember Data.

The Store specifies:

DS.RESTAdapter.configure("plurals", {
  image: 'images',
  gallery: 'galleries',
  comment: 'comments'
});
DS.RESTAdapter.configure('App.Image', {
  sideloadAs: 'images'
});
DS.RESTAdapter.configure('App.Comment', {
  sideloadAs: 'comments'
});
App.store = DS.Store.create({
  revision: 11,
  adapter: DS.RESTAdapter.create({
    mappings: {
      comments: 'App.Comment'
    }
  })
});

I am fairly sure you don't need the plurals definitions if your data is normal words like images and things. My domain is conceptually close to these but rather more technical. I chose to post with these names to make the concepts and relationships more generally understandable.

My models contain the following ... among all the other usual stuff.

App.Gallery = DS.Model.extend({
  images: DS.hasMany('App.Image',{key: 'images', embbeded: true})
});

App.Image = DS.Model.extend({
  comments: DS.hasMany('App.Comment',{key: 'comments', embedded: true}),
  gallery: DS.belongsTo('App.Gallery')
});

App.Comment = DS.Model.extend({
  image: DS.belongsTo('App.Image')
});

This allows me to return a json structure like the one in my question:

{"comments":[...],"images":[...],"galleries":{"id":1,...,"images":[1,2,3]}}

This is produces from Rails using ActiveModelSerializers. My serializers look like this:

class ApplicationSerializer < ActiveModel::Serializer
  embed :ids, :include => true
end
class GallerySerializer < ApplicationSerializer
  attributes :id, ...
  root "gallery"
  has_many :images, key: :images, root: :images
end
class ImageSerializer < ApplicationSerializer
  attributes  :id, ...
  root "image"
  has_many :comments, key: :comments, root: :comments
end
class CommentSerializer < ApplicationSerializer
  attributes  :id, ...
end

Again. I think you can get away with being much less verbose. My rails models are not simple called "Gallery". They are name spaced in something like "BlogGallery" but I did not want Ember to have to deal with all that. I need the key and root things for this reason.

I think that covers all I have regarding associations and embedding them in the same json response.