1
votes

I'm using Ember 2.4.1 and trying to build the hierarchical tree with self reference model.

Here is the my Ember model

// app/models/category.js
import DS from 'ember-data';
export default DS.Model.extend({
    name: DS.attr('string'),
    parent: DS.belongsTo('category', { inverse: 'children' }),
    children: DS.hasMany('category', { embedded: 'always', async: false, inverse: 'parent' })
});

And server response in route /categories with embedded data (I use RESTAdapter on Ember side):

{"categories":[
    {
        "id":4,
        "name":"Root element w/o children",
        "type":"Category",
        "children":[]
    },
    {
        "id":5,
        "name":"Root element with a child",
        "type":"Category",
        "children":[
            {
                "id":6,
                "name":"A child",
                "type":"Category",
                "children":[]
            }
        ]
    }
]}

As you can see Category with id 5 has a child with id 6 and it embedded. But while Ember loading the page it makes an error: Assertion Failed: You looked up the 'children' relationship on a 'category' with id 5 but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (DS.hasMany({ async: true }))

If I include the category with id 6 in JSON-root like {categories: [{id:4, …}, {id:5, …}, {id:6, …}]} error will disappear but I don't know why I need embedding in this case. May be I don't understand how embedding works in Ember.

So I'd like to ask advice how to make properly work Ember Data with embedded response without duplicating it and without async: true.

UPD @TheCompiler answered on my question in comments. Adding serializer with mixin solve my problem:

// app/serializers/category.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
    attrs: {
        children: { embedded: 'always' }
    }
});
1

1 Answers

0
votes

No need to duplicate the record. The Rest Adapter just doesn't play nice with nested JSON objects. Try formatting the data like this:

{"categories":[
    {
        "id":4,
        "name":"Root element w/o children",
        "type":"Category",
        "children":[]
    },
    {
        "id":5,
        "name":"Root element with a child",
        "type":"Category",
        "children":[6]
    },
    {
        "id":6,
        "name":"A child",
        "type":"Category",
        "children":[]
    }
]}