0

I have an emberjs application backed by a nodejs server and mongodb. Currently my database is sending documents with an '_id' field. I have the followign code to force Ember to treat '_id' as the primary key:

App.ApplicationSerializer = DS.RESTSerializer.extend({
   primaryKey: '_id'
});

On the other hand i have two models related by a 'hasMany' relationship as such:

App.Player = DS.Model.extend({
 name: DS.attr('string'),
 thumbLink: DS.attr('string'),
 activeGame: DS.belongsTo('game', { async: true }),
 email: DS.attr('string'),
 firstName: DS.attr('string'),
 lastName: DS.attr('string'),
 admin: DS.attr('boolean')
});

App.Game = DS.Model.extend({
  name: DS.attr('string'),
  active: DS.attr('boolean'),
  players: DS.hasMany('player', { async: true })
});

The problem is that when i try to save the model ( this.get('model').save() )on my controller the ids are not serialized and the result is ember sending the following:

{"game":{"name":"Indie/Rock","active":false,"players":[],"_id":"53cbbf43daa978983ee0b101"}}

As you can see the players array is empty, and as a result, the server is saving that empty array which in fact is not correct. I am aware that it is possible to use { embedded: true } on the models and return the models with embedded documents from the server, but i want to preserve the async feature.

I have tried to extend the game serializer from EmbeddedRecordsMixing as the following:

App.GameSerializer = DS.ActiveModelSerializer
                   .extend(DS.EmbeddedRecordsMixin)
                   .extend({
                     attrs: {
                       players: {serialize: 'ids', deserialize: 'ids'},
                     }
                   });

But when i do so i get the following error from ember even though the ApplicationSerializer is suppossedly telling Ember to user _id as primary key:

Assertion Failed: Error: Assertion Failed: You must include an `id` for App.Game in a hash passed to `push` 

My question is if it is possible to maintain the async features of ember-data while being able to serialize the document with the ids on it's relation and using _id as a primary key.

Thank you.

Rafls
  • 1
  • Also mentioned in http://stackoverflow.com/questions/24125334/ember-js-quiz-questions-save-delete-hasmany-data/24130793#24130793 – Kingpin2k Jul 20 '14 at 15:33

1 Answers1

3

Ember Data is stupid in this aspect, if it's a ManyToOne relationship, it only includes the id from the belongsTo side. Honestly I've had it on my bucket list to submit a PR, but time is limited.

https://github.com/emberjs/data/commit/7f752ad15eb9b9454e3da3f4e0b8c487cdc70ff0#commitcomment-4923439

App.ApplicationSerializer = DS.RESTSerializer.extend({

 serializeHasMany: function(record, json, relationship) {
    var key = relationship.key;
    var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, "hasMany") : key;
    var relationshipType = RelationshipChange.determineRelationshipType(record.constructor, relationship);

    if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany'
        || relationshipType === 'manyToOne') {  // This is the change
      json[payloadKey] = get(record, key).mapBy('id');
      // TODO support for polymorphic manyToNone and manyToMany relationships
    }
  },
});
Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
  • I already have that code on my app, but it does not solve the problem. If i do a console.log(record) and console.log(json) inside the serializeHasMany method the players array is empty although the data coming from the sever on the /api/games call has the players array filled... – Rafls Jul 20 '14 at 18:52
  • I'm saying that code removes the array on save. It only saves from the belongsTo side. – Kingpin2k Jul 20 '14 at 20:16
  • Ok, i misunderstood you, anyway still no solution, right? – Rafls Jul 21 '14 at 07:33
  • Correct, the current implementation of Ember Data doesn't support it without overriding the `serializeHasMany` (I'll show an example) – Kingpin2k Jul 21 '14 at 14:14