本文介绍了在保存emberjs模型时序列化ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我拥有一个由nodejs服务器和 mongodb 支持的 emberjs 应用程序。目前,我的数据库正在发送带有'_ id'字段的文档。我有以下代码强制Ember将对待'_id'作为主键

 应用程序.ApplicationSerializer = DS.RESTSerializer.extend({
primaryKey:'_id'
});

另一方面,我有两个与hasMany关系相关的模型:

  App.Player = DS.Model.extend({
name:DS.attr('string'),
thumbLink:DS.attr('string'),
activeGame:DS.belongsTo('game',{async:true}),
电子邮件: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'),
玩家:DS.hasMany('player',{async:true})
});

问题是当我尝试保存模型 this.get('model')。save())在控制器上,ids不是序列化的,结果是发送以下内容的ember:

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

你可以看到球员阵列是,因此,服务器正在保存空数组,这实际上是不正确的。我知道可以在模型上使用 {embedded:true} ,并从服务器返回带有嵌入式文档的模型,但是我想保留异步功能。



我尝试从 EmbeddedRecordsMixing 游戏序列化程序 c>如下:

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

但是当我这样做时,即使ApplicationSerializer绝对告诉Ember,用户_id作为主键:

 断言失败:错误:断言失败:您必须在App.Game中包含一个id传递给`push`的哈希

我的问题是如果可以维护异步 ember-data的功能,同时可以使用 ids 序列化文档,并使用_id作为主键。



谢谢。

解决方案

Ember数据在这方面是愚蠢的,如果它是一个ManyToOne关系,它只包括 belongsTo 侧。老实说,我已经在我的桶列表上提交公关,但时间有限。





$ pre> App.ApplicationSerializer = DS.RESTSerializer.extend({

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

if(relationshipType ==='manyToNone'|| relationshipType ==='manyToMany'
|| relationshipType ==='manyToOne'){//这是更改
json [payloadKey ] = get(record,key).mapBy('id');
// TODO支持多态无数和多对多关系
}
},
});


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.

解决方案

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
    }
  },
});

这篇关于在保存emberjs模型时序列化ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 16:31