Ember 数据 - 使用 属性 而不是 hasMany 关系的 id
Ember data - use property other than id for hasMany relationship
我的 tag
和 payment
模型之间定义了多对多关系,如下所示。
//models/tag.js
import Model, { attr, hasMany } from '@ember-data/model';
export default Model.extend({
name: attr('string'),
backgroundColour: attr('string'),
textColour: attr('string'),
payments: hasMany('payment')
});
// models/payment.js
import Model, { attr, hasMany } from '@ember-data/model';
export default Model.extend({
date: attr('date'),
amount: attr('number'),
paymentId: attr('string'),
tags: hasMany('tag'),
});
默认情况下,当我向付款添加标签时,付款的 id
用作关系的键。我的目标是让 Ember 数据使用 paymentId
属性 作为这种关系的关键。
下面的代码片段显示了我正在加载的数据的结构,其中标签引用了 paymentId
属性.
的付款
// Example tag
{
"id": "25",
"name": "Groceries",
"backgroundColour": "31b04b",
"textColour": "ffffff",
"payments": ["20190121201902210"] // References paymentId rather than id
},
// Example payment
{
"id": "1"
"date": "2019-01-27T22:00:00.000Z",
"amount": 1644.44,
"paymentId": "20190121201902210",
"tags": ["25"]
}
我尝试按如下方式自定义支付序列化程序,
// serializers/payment.js
import ApplicationSerializer from './application';
export default ApplicationSerializer.extend({
keyForRelationship(key, _relationship) {
if (key === 'payments') {
return 'paymentId';
}
},
});
但是,在加载模型时出现此错误:Assertion Failed: All elements of a hasMany relationship must be instances of Model, you passed [ "20190121201902210" ]
。
如何在查找相关付款时使 Ember 数据使用 paymentId
而不是 id
?
我假设您正在使用 RESTSerializer
。它有一个 primaryKey
option,如果您的 API 负载中的主键未命名为 id
,则应使用它。
您的示例似乎有点困难,因为该记录似乎有两个主键:id
和 paymentId
。如果只有其中一个用于引用相关记录,我建议直接忽略另一个。
如果两者都用来引用相关记录,那你就惨了。也许你可以更改 API?
如果这不可能,我想您需要在序列化程序中将一个 ID 映射到另一个 ID,这需要之前加载付款记录。这变得很棘手,因为序列化程序是同步的,这意味着必须先加载记录。我想在这样的解决方案稳定之前你会遇到很多边缘情况 - 打破它会很容易,因为它在很大程度上取决于时间。
因此,也许您甚至应该考虑根本不对这些资源使用 Ember 数据。它在很大程度上取决于每个资源都可以通过其类型和 ID 的组合来识别的假设。但听起来对你来说同一个资源可以用两个不同的 ID 来识别。
我的 tag
和 payment
模型之间定义了多对多关系,如下所示。
//models/tag.js
import Model, { attr, hasMany } from '@ember-data/model';
export default Model.extend({
name: attr('string'),
backgroundColour: attr('string'),
textColour: attr('string'),
payments: hasMany('payment')
});
// models/payment.js
import Model, { attr, hasMany } from '@ember-data/model';
export default Model.extend({
date: attr('date'),
amount: attr('number'),
paymentId: attr('string'),
tags: hasMany('tag'),
});
默认情况下,当我向付款添加标签时,付款的 id
用作关系的键。我的目标是让 Ember 数据使用 paymentId
属性 作为这种关系的关键。
下面的代码片段显示了我正在加载的数据的结构,其中标签引用了 paymentId
属性.
// Example tag
{
"id": "25",
"name": "Groceries",
"backgroundColour": "31b04b",
"textColour": "ffffff",
"payments": ["20190121201902210"] // References paymentId rather than id
},
// Example payment
{
"id": "1"
"date": "2019-01-27T22:00:00.000Z",
"amount": 1644.44,
"paymentId": "20190121201902210",
"tags": ["25"]
}
我尝试按如下方式自定义支付序列化程序,
// serializers/payment.js
import ApplicationSerializer from './application';
export default ApplicationSerializer.extend({
keyForRelationship(key, _relationship) {
if (key === 'payments') {
return 'paymentId';
}
},
});
但是,在加载模型时出现此错误:Assertion Failed: All elements of a hasMany relationship must be instances of Model, you passed [ "20190121201902210" ]
。
如何在查找相关付款时使 Ember 数据使用 paymentId
而不是 id
?
我假设您正在使用 RESTSerializer
。它有一个 primaryKey
option,如果您的 API 负载中的主键未命名为 id
,则应使用它。
您的示例似乎有点困难,因为该记录似乎有两个主键:id
和 paymentId
。如果只有其中一个用于引用相关记录,我建议直接忽略另一个。
如果两者都用来引用相关记录,那你就惨了。也许你可以更改 API?
如果这不可能,我想您需要在序列化程序中将一个 ID 映射到另一个 ID,这需要之前加载付款记录。这变得很棘手,因为序列化程序是同步的,这意味着必须先加载记录。我想在这样的解决方案稳定之前你会遇到很多边缘情况 - 打破它会很容易,因为它在很大程度上取决于时间。
因此,也许您甚至应该考虑根本不对这些资源使用 Ember 数据。它在很大程度上取决于每个资源都可以通过其类型和 ID 的组合来识别的假设。但听起来对你来说同一个资源可以用两个不同的 ID 来识别。