【问题标题】:Record saves, promise rejects with custom REST adapter使用自定义 REST 适配器记录保存、承诺拒绝
【发布时间】:2014-09-05 03:08:13
【问题描述】:

我正在为 DreamFactory 服务平台编写一个 ember-data 适配器,遇到了一个我认为与我的适配器有关的问题。

更新现有记录时,model.save() 产生的承诺总是被拒绝,错误为

Assertion Failed: An adapter cannot assign a new id to a record that already has an id. <App.Event311:1> had id: 1 and you tried to update it with null. This likely happened because your server returned data in response to a find or update that had a different id than the one you sent

问题是 - 对 REST API 的请求和从 REST API 返回的响应具有相同的 ID!

请求(PUT)

{ "record": { "id": "1", "title": "Sample Event", "date": "7/20/2013", "type": "success", "desc": "My first sample event." } }

响应

{ "record": [ { "id": 1, "title": "Sample Event", "date": "7/20/2013", "type": "success", "desc": "My first sample event." } ] }

真正奇怪的是记录仍然在存储中正确更新在数据库中!

我在http://emberjs.jsbin.com/mosek/1/edit 有一个可以工作的 JSBin,它说明了这个问题。我的自定义适配器位于 GitHub 上的 https://github.com/ultimatemonty/ember-data-dreamfactory-adapter。 JSBin 和我的应用程序正在使用 Ember 1.7.0 和 ED 1.0.0-beta.9

编辑

JSBin 附加到我的 DreamFactory 个人托管实例 - 除了允许从 JSBin 访问之外,我没有对它做任何事情,但请保持温和 :)

* 编辑 #2 *

updateRecord 代码可在 GitHub 上的 https://github.com/ultimatemonty/ember-data-dreamfactory-adapter/blob/master/lib/ember-data-dreamfactory-adapter.js#L106 访问,但这里是完整的参考方法:

updateRecord: function(store, type, record) {
    var data = {};
    var serializer = store.serializerFor(type.typeKey);
    serializer.serializeIntoHash(data, type, record);
    var adapter = this;

    return new Ember.RSVP.Promise(function(resolve, reject) {
        // hack to make DSP send back the full object
        adapter.ajax(adapter.buildURL(type.typeKey) + '?fields=*', "PUT", { data: data }).then(function(json){
            // if the request is a success we'll return the same data we passed in
            resolve(json);
        }, function(reason){
            reject(reason.responseJSON);
        });
    });
}

【问题讨论】:

  • 错误信息说您不能使用 id 发帖。为什么不删除id? Ember Data 期望服务器分配它。
  • @torazaburo 这是对现有模型的更新,所以我需要 id 来执行更新。
  • 在 ajax 请求之后尝试从您的商店中卸载记录。
  • 更新是 PUT,而不是 POST。

标签: rest ember.js ember-data


【解决方案1】:

您正在使用的适配器/序列化器期望您返回没有类型的响应:

{ 
    "id": 1,
    "title": "Sample Event",
    "date": "7/20/2013",
    "type": "success",
    "desc": "My first sample event."
}

示例:http://emberjs.jsbin.com/tigiza/1/edit

您可以在extractSingle 中看到它,它会尝试将有效负载包装在具有指定类型的另一个对象中

EmberDreamFactoryAdapter.Serializer = DS.RESTSerializer.extend({

    extractArray: function(store, primaryType, payload) {
        var namespacedPayload = {};
        namespacedPayload[Ember.String.pluralize(primaryType.typeKey)] = payload.record;
        return this._super(store, primaryType, namespacedPayload);
    },

    extractSingle: function (store, primaryType, payload, recordId) {
        var namespacedPayload = {};
        namespacedPayload[primaryType.typeKey] = payload;
        return this._super(store, primaryType, namespacedPayload, recordId);
    },

您的回复如下所示:

{
    "record": [
        {
            "id": 1,
            "title": "Sample Event",
            "date": "7/20/2013",
            "type": "success",
            "desc": "My first sample event."
        }
    ]
}

然后序列化器启动,它看起来像这样:

{
    event:{
       "record": [
          {
            "id": 1,
            "title": "Sample Event",
            "date": "7/20/2013",
            "type": "success",
            "desc": "My first sample event."
          }
      ]
   }
}

如果真的,序列化程序应该看起来像这样:

{ 
  event:{
    "id": 1,
    "title": "Sample Event",
    "date": "7/20/2013",
    "type": "success",
    "desc": "My first sample event."
  }
}

从第二个例子可以看出,序列化器将它包装在类型中,然后 Ember Data 说,嘿,给我 id,所以它查看 event.id 这是未定义的,因为它位于 event.record[0].id

【讨论】:

  • 在看了你的例子之后,这是有道理的。我的理解是,ED 期望除 DELETE 之外的所有 REST 响应都具有 JSON 根元素——该请求就是这样做的。 PUT 响应不是这种情况吗?
  • 正确,但是您使用的序列化程序将响应包装在类型中,但最终将其深度提高了两层(答案已更新)
  • 感谢详细的解释!我真正的问题是我需要将请求包装在 record 元素中,因为这是 DreamFactory API 所期望的,但我想我需要不修改响应 - 我想我需要为我的 GET 请求并让 updateRecordcreateRecord 方法使用默认的 serializeIntoHash 实现?
  • 在阅读文档时,我误解了extractSave is an alias for extractSingle,因为我已经覆盖了 extractSingle,因此我正在做需要做的事情。明显不是!再次感谢您的帮助!
猜你喜欢
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 2019-11-25
  • 2016-01-23
  • 2016-07-05
  • 2017-09-04
相关资源
最近更新 更多