DS.FixtureAdapter loses fixture data with hasMany async attributes

跟風遠走 提交于 2019-12-11 03:46:45

问题


Background

I've already submitted a github issue with the Ember Data team, but I'd love insight into how to work around this (or if I was mistaken all along)

You can see a working demo if this bug on jsfiddle

The problem

jsfiddle of the issue here: http://jsfiddle.net/cdownie/JxhBv/1/ Code is duplicated here for a clearer explanation.

The setup

I have the following data model that I'd like to test with fixtures:

App.Parent = DS.Model.extend({
    name: DS.attr('name'),
    kids: DS.hasMany('kids', {async : true})
});
App.Kid = DS.Model.extend({
    name: DS.attr('name'),
    grade: DS.attr('string')
});

I'm using the following fixtures to test it:

App.Parent.FIXTURES = [
    {id: 'doe', name: 'john', links: {kids: '/fake/url/for/kids'}}
];
App.Kid.FIXTURES = [
    {id: 'doe-jr', name: 'john jr', grade: '4th'}
];

Now, DS.FixtureAdapter by default doesn't support this kind of relationship, so I had to write my own extension that filled out the findHasMany method. In this implementation, I use the parent ID as a prefix for all the children.

App.CustomFixtureAdapter = DS.FixtureAdapter.extend({
    defaultSerializer: '_umrest',

    findHasMany: function(store, record, link, relationship) {
        var type = relationship.type;
        var parentId = record.get('id');
        return store.findAll(relationship.type).then(function(children) {
            var content = children.get('content');
            var filteredContent = content.filter(function(child) {
                return (child.get('id').indexOf(parentId) == 0);
            });

            // The children we return here are fully resolved with data.
            var kid = filteredContent[0];
            console.log('The findHasMany method is returning a kid with id      :', kid.get('id'),  ' name: ', kid.get('name'), ' grade:', kid.get('grade'));

            return Ember.RSVP.resolve(filteredContent);
        });
    },

    queryFixtures: function(fixtures, query, type) {
        return fixtures;
    }
});

The bug

Inside findHasMany, my App.Kid entity is fully resolved. All its data is there. However, in any other code that requests a parent's kid, the App.Kid model has an ID but no other data. In my demo, this is demonstrated in the index route:

App.IndexRoute = Ember.Route.extend({
    model: function() {
        // Return the first kid of the first parent (in our data: the only kid)
        return this.store.findAll('parent').then(function(parentRecords) {
            var parent = parentRecords.get('content')[0];
            return parent.get('kids').then(function(kids) {
                return kids.get('content')[0];
            });
        });
    },
    setupController: function(controller, model) {
        var id = model.get('id'), 
            name = model.get('name'), 
            grade = model.get('grade');

        console.log('The model in setupController is returning a kid with id:', id,  ' name: ', name, ' grade:', grade);

        console.log('Is that model fully loaded?', model.get('isLoaded') ? 'yes': 'no');

        controller.set('id', id);
        controller.set('name', name);
        controller.set('grade', grade);
    }
});

Expected behavior

Since we get a fully-resolved App.Kid model from a store.findAll(U.Kid) call in the custom fixture adapter, I'd expect that fully resolved model to be present when I get that model through the hasMany relationship.

Environment

In the js fiddle:

DEBUG: Ember      : 1.6.1
DEBUG: Ember Data : 1.0.0-beta.8.2a68c63a
DEBUG: Handlebars : 1.0.0
DEBUG: jQuery     : 1.8.3

In another environment as well:

DEBUG: Ember      : 1.5.1
DEBUG: Ember Data : 1.0.0-beta.8.2a68c63a
DEBUG: Handlebars : 1.0.0
DEBUG: jQuery     : 1.9.1

回答1:


I figured it out. The problem is in my implementation of findHasMany. The system expects an array of vanilla data objects, like:

[{id: 'doe-jr', name: 'john jr', grade: '4th'}]

when what I was actually returning was an array of App.Kid models.

Modified method is below:

findHasMany: function(store, record, link, relationship) {
    var type = relationship.type;
    var parentId = record.get('id');
    return store.findAll(relationship.type).then(function(children) {
        var content = children.get('content');
        var filteredContent = content.filter(function(child) {
            return (child.get('id').indexOf(parentId) == 0);
        });
        // Fixed the issue by pulling out the raw data from the fixture model 
        // and returning that.
        var data = filteredContent.map(function(content) {
            return content.get('data');
        });

        return Ember.RSVP.resolve(data);
        // Switch that return statement to the following to show original bug:
        // return Ember.RSVP.resolve(filteredContent);
    });
},


来源:https://stackoverflow.com/questions/25043438/ds-fixtureadapter-loses-fixture-data-with-hasmany-async-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!