Ember Data fixture adapter saving record loses has many relationships


#1

I am having issues working with the Ember Data fixture adapter. When saving a record, all it’s hasMany relationships are lost.

My models and fixtures look like:

App.User = DS.Model.extend({
  name: DS.attr('string'),
  projects: DS.hasMany('project', { async: true})
});

App.Project = DS.Model.extend({
  name: DS.attr('string'),
  user: DS.belongsTo('user')
});

App.User.FIXTURES = [
  { id: 1, name: 'Kris', projects: [1,2] },
  { id: 2, name: 'Luke', projects: [1,2] }
];

App.Project.FIXTURES = [
  { id: 1, name: 'Ember' },
  { id: 2, name: 'Angular' }
];

And I am saving the record using:

App.UsersRoute = Ember.Route.extend({
  actions: {
    save: function(model) {
      var self = this;
      model.save().then(function() {
        this.transitionTo('users');
      });
    }
  },
  model: function(){ 
    return this.store.find('user');
  }
});

I have create a JS Bin to illustrate the issue and also posted on Stackoverflow.

Thanks


#2

Seems like DS.JSONSerializer.serializeHasMany ignores manyToOne when serializing. I am getting around this by creating a custom serializer for the model and overwritting serializeHasMany so that it handles manyToOne relationship types.

var get = Ember.get;
App.UserSerializer = DS.RESTSerializer.extend({
  serializeHasMany: function(record, json, relationship) {
    var key = relationship.key;

    var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship);

    if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany' || relationshipType === 'manyToOne') {
      json[key] = get(record, key).mapBy('id');
      // TODO support for polymorphic manyToNone and manyToMany relationships
    }
  }
});

#3

I hit the same problem and came to the same solution. Surely this is a bug in ember-data?

Here’s my solution, the only difference is that I’m modifying JSONSerializer, rather than extended RESTSerializer because I’m using the local storage adapter.:

DS.JSONSerializer.reopen({
    serializeHasMany : function(record, json, relationship) {
        var key = relationship.key;

        var relationshipType = DS.RelationshipChange.determineRelationshipType(
                record.constructor, relationship);

        if (relationshipType === 'manyToNone'
                || relationshipType === 'manyToMany'
                || relationshipType === 'manyToOne') {
            json[key] = Ember.get(record, key).mapBy('id');
            // TODO support for polymorphic manyToNone and manyToMany
            // relationships
        }
    }
});

#4

I ran into this issue as well. I didn’t realize until I found this question that other people have fixed the issue, but it still seems to be a problem on ember/data master. I fixed it by updating my local copy of emaber-data-1.0.0.beta-3.js directly. Seems like we should create an issue in the ember/data Github repo.

Also, I saw this using the local-storage-adapter, so it’s not exclusive to the fixture adapter.


#5

Same issue here as well. I am also using fixture adapter.

Your solution fixed the problem. Is this really a bug? Or there is something wrong with our code?


#6

@billcchkk could you open a PR against emberjs/data? I’m facing this same problem here while writing my tests.

@jefkoslowski My App.Cart hasMany App.Items. After .createRecord() is called, cart.get('items.length') is 1, but as soon as I call cart.save(), cart.get('items.length') returns 0. It’s definitely a bug in Ember Data.

Thanks.


Saving multiple hasMany
#7

Guys, I opened this PR with a failing spec, https://github.com/emberjs/data/pull/1606

If you guys think it makes sense, could you chime in?


#8

I’ve just started out using the Fixture adapter, and ran into this. However, perhaps there are two separate issues here? The back-end I’ll be using will create a reciprocal “hasMany” for a “belongsTo” – so I have no need to write back the hasMany via REST: perhaps this should be configurable?

On the other hand, the Fixture adapter should clearly not loose hasMany on save – that is clearly a bug. Indeed from my POV the fixture adapter should automatically sync hasMany from related belongsTo… Any thoughts on this?


#9

I also created a PR, https://github.com/emberjs/data/pull/1751 which adds the check for manyToOne