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 :s - sly7_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.