如何使用 JSON API 属性覆盖主键

How to override the primary key with a JSON API attribute

我有一个名为 "Membership" 的模型,它有一个字符串属性 "inviteToken",我想将其用作我的主键。

我创建了以下序列化程序,但无法让它从 JSON 中获取主键。

app/serializers/membership.js:

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  primaryKey: 'invite-token' // also tried 'inviteToken'
});

我遇到的具体错误是:

Error while processing route: invitations.show Assertion Failed: You must include an 'id' for membership in an object passed to 'push'
Error: Assertion Failed: You must include an 'id' for membership in an object passed to 'push'

当我尝试通过路由中的 ID 获取记录时会发生这种情况:

import Ember from 'ember';

export default Ember.Route.extend({
  model(params) {
    return this.store.find('membership', params.token);
  }
});

API 响应:

{
  "jsonapi":{
    "version":"1.0"
  },
  "data":{
    "type":"membership",
    "id":"30",
    "attributes":{
      "invite-token":"5bGo7IhZh93E4SB07VWauw"
    }
  }
}

奇怪的是,如果我使用 "type" 作为主键,我会在 ember 检查器中看到 "membership" 作为 id。就好像 ember 数据不知道如何使用来自 "attributes" 的东西。我正在使用 ember 数据 2.4.0.

更新

我可以通过这样做来破解它以在我的序列化程序中工作:

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  normalize: function(type, hash) {
    const json =  this._super(type, hash);
    json.data.id = json.data.attributes.inviteToken;

    return json;
  }
});

序列化程序期望 primaryKey 的值引用 json 中的顶级元素。这就是 "type" 和 "id" 起作用的原因。目前不支持嵌套属性(例如primaryKey: "attributes.invite-token")

但是有两个很好的解决方法:

首先是覆盖 extractId 方法。 default implementation 非常简单。在您的情况下,您可以执行以下操作:

extractId(modelClass, resourceHash) {
    var id = resourceHash['attributes']['invite-key';
    return coerceId(id);
  },

第二种方法就是你发现的方法,比较暴力的方法,就是在normalize函数中手动分配id。