Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to get hasMany association

I used commit eaa1123 (ember) and 508479d (ember-data) to build the JS files.

I have the following JSON returned from my Rails backend, which is generated with active_model_serializers (0.6.0):

{
  "posts": [
    {
      "id": 408,
      "title": "Lorem Ipsum",
      "body": "In at quo tempora provident nemo.",
      "comments": [
        {
          "id": 956,
          "body": "Quo incidunt eum dolorem."
        },
        ...
      ]
    }
  ]
}

and the following Ember models:

App.Post = DS.Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string'),
  comments: DS.hasMany('App.Comment', {
    embedded: true
  })
});

App.Comment = DS.Model.extend({
  body: DS.attr('string'),
  post: DS.belongsTo('App.Post')
});

All look perfectly normal:

post = App.Post.find(408);
post.get('title')
// => "Lorem Ipsum"

However, I can't seem to get to the comments:

comments = post.get('comments')
comments.get('firstObject') instanceof App.Comment
// => true
comments.forEach(function(comment) {
  console.log(comment.get('body'))
})
//=> undefined

When I use:

comments.content

I get an Array that contain objects, so:

comments.content[0]
//=> { body: "Quo incidunt eum dolorem.", id: 956 }

but this is not what I expected.

It seems so obvious, so I must be doing something wrong. As a side-effect: currently I'm not able to render my comments in a template in a easy way, so I hope someone can help me on this one.

Thanks in advance.

like image 343
bazzel Avatar asked Jan 05 '13 09:01

bazzel


1 Answers

If you used that commit it means you are on the latest ember-data revision, which is 11. Adding embedded: true to load an embedded association was deprecated a while back between revision 5 or 9, not too sure again.

If you are using the default restAdapter, you now need to define embedded loading as a mapping as shown below and not as an association option:

App.store = DS.Store.create({
  revision: 11,
  adapter: DS.RESTAdapter.create()
});

App.store.adapter.serializer.map('App.Post', {
   comments: {embedded: 'load'}
});

App.Post = DS.Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string'),
  comments: DS.hasMany('App.Comment')
});

App.Comment = DS.Model.extend({
   body: DS.attr('string'),
   post: DS.belongsTo('App.Post')
});

You can follow all the previous discussion on it through the links below:

https://github.com/emberjs/data/issues/504#issuecomment-11256934 https://github.com/emberjs/data/pull/430#issuecomment-10925506

Various fixes for loading embedded records: https://github.com/emberjs/data/pull/541

This not directly related but incase all i wrote above fails, then add this solution to the mix BelongsTo association are not materialized when using findAssociation and extractHasMany hooks for async HasMany: https://github.com/emberjs/data/issues/525

The internals for anyone who wants to quickly see where things are defined with respect to the call to 'App.store.adapter.serializer.map'

When we called 'App.store.adapter.serializer.map', the call to serializer is defined on line 536 below and the map is online 696 in the 2nd link

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/adapter.js#L536 https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/adapter.js#L696

On line 67 of the DS.RESTAdapter which extends DS.Adapter, the serializer property is made to point to DS.RESTSerializer where additional functionality specific to the RestAdapter are added.

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L67

like image 118
brg Avatar answered Nov 18 '22 19:11

brg