Ember数据保存了一段感情

时间:2013-02-28 14:39:04

标签: javascript ember.js ember-data

我很难在ember数据中保存一对多的关系。我有这样的关系:

App.ParameterSet = DS.Model
    name: DS.attr("string")
    regions: DS.hasMany("App.Region")

App.Region = DS.Model
    name: DS.attr("string")

如果我要做这样的事情:

parameterSet = App.ParameterSet.find(5)
@transaction = @get("store").transaction()
@transaction.add(parameterSet)
region1 = App.Region.find(10)
region2 = App.Region.find(11)
parameterSet.set("name", "foo")
parameterSet.get("regions").pushObject(region)
@transaction.commit()

然后我希望看到带有这样的有效负载的PUT请求:

api/ParameterSets/5

{parameterSet: {name: "foo", regionIds:[10, 11]}}

但我得到了这个:

{parameterSet: {name: "foo"}}

我不关心从孩子到父母之间的关系,但如果我将parameterSet: DS.belongsTo("App.ParameterSet")添加到App.Region模型,那么我会向两个新关系获取2个PUT请求到区域url我想要的是。

我想这是一个多对多的关系,我不确定它是否支持,但有关如何实现我所描述的任何想法?感谢

2 个答案:

答案 0 :(得分:8)

hasMany关系的序列化由addHasMany()的{​​{1}}方法处理。

以下注释包含在source code

  

默认的REST语义只是添加有多个关系   嵌入式。如果最初通过ID加载关系,我们会假设   这是作为性能优化完成的,并且改变了   has-many应保存为子项所属的外键更改   关系。

要实现您的目标,一个选项是指示关系应该嵌入适配器中。

json_serializer.js

当然,现在你的后端需要在参数集的JSON中实际嵌入关联区域的JSON。如果您想保持原样,只需使用自定义序列化覆盖App.Store = DS.Store.extend({ adapter: DS.RESTAdapter.extend({ serializer: DS.RESTSerializer.extend({ init: function() { this._super(); this.map('App.ParameterSet', { regions: { embedded: 'always' } }); } }) }) });

addHasMany()

答案 1 :(得分:2)

我无法在ahmacleod的答案中添加注释,但除了我注意到在修改子记录时父记录没有被标记为脏时,它是现场的。在问题的示例中,不会出现问题,因为父记录上也修改了名称。

但是,一般情况下,如果您要遵循ahmacleod的第二个答案,则需要覆盖RESTAdapter上的dirtyRecordsForHasManyChange方法。否则,永远不会调用序列化程序中的addHasMany,因为记录甚至没有标记为脏。

现有方法如下:

dirtyRecordsForHasManyChange: function(dirtySet, record, relationship) {
  var embeddedType = get(this, 'serializer').embeddedType(record.constructor, relationship.secondRecordName);

  if (embeddedType === 'always') {
    relationship.childReference.parent = relationship.parentReference;
    this._dirtyTree(dirtySet, record);
  }
},

所以我想你会想要这样的东西:

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.extend({
    dirtyRecordsForHasManyChange: function(dirtySet, record, relationship) {
      relationship.childReference.parent = relationship.parentReference;
      this._dirtyTree(dirtySet, record);
    },

    serializer: DS.RESTSerializer.extend({
      addHasMany: function(hash, record, key, relationship) {
        // custom ...
      }
    })
  })
});