Normalizr - 如何生成与父实体相关的slug / id [英] Normalizr - How to generate slug/id related to parent entity
问题描述
如何使用 normalizr 分配与实体父母相关的id / slug?
How can I assign id/slug related to the entity's parent using normalizr?
示例:
用户来电的API响应:
API Response for a user call:
{
id: '12345',
firstName: 'John',
images: [
{
url: 'https://www.domain.com/image0',
name: 'image0'
},
{
url: 'https://www.domain.com/image1',
name: 'image1'
}
]
}
我可以通过以下方式定义我的模式:
I could define my schemas in the following way:
const image = new Schema('images');
const user = new Schema('users');
user.define({
images: arrayOf(image)
})
问题是图像没有 id
属性,因此除非我们提供<$ c,否则normalizr将无法区分它们$ c> id property。当然,我们可以做类似的事情
The problem is that images don't have an id
property, so normalizr will not be able to distinguish them unless we provide an id
property. Of course, we could do something like
const image = new Schema('images', { idAttribute: uuid.v4() });
并生成唯一标识符。
假设我们收到用户更新,图片名称已更新。因为我们在每个规范化中生成唯一标识符,所以我们无法识别和更新现有图像。
Suppose we receive a user update and an image's name has been updated. Because we generate unique identifiers in every normalization, we are not able to identify and update the existing image.
我需要一种方法来引用父实体(用户)图像实体(在其id / slug中,如 12345-image0
, 12345-image1
或作为单独的财产。
I need a way to reference the parent entity (user) in the image entity (either in its id/slug like 12345-image0
, 12345-image1
or as a separate property.
实现这一目标的最佳方法是什么?
What would be the optimal way to achieve this?
推荐答案
问题
以你显示的方式使用uuid将无效。
Problem
Using uuid the way you show will not work.
const image = new Schema('images', { idAttribute: uuid.v4() });
uuid.v4()
返回一个字符串, idAttribute
的可接受值,但现在所有图像
将拥有相同的uid。不是你想要的。
uuid.v4()
returns a string, an acceptable value for idAttribute
but now all your images
will have the same uid. Not what you want.
理想情况下这可行:
const image = new Schema('images', { idAttribute: () => uuid.v4() });
不幸的是, idAttribute
将被多次调用,如上所述在本期中。这将破坏任何实体关系。在您的示例中,图像将具有与用户实体引用它们不同的uid。
Unfortunately, idAttribute
will be invoked multiple times, as mentioned in this issue. This will break any entity relations. In your example, the images will have different uids than what the user entity references them as.
示例输出:
users: {
'12345': {
id: '12345',
firstName: 'John',
images: [
"cj20qq7zl00053j5ws9enz4w6",
"cj20q44vj00053j5wauawlr4u"
],
}
};
images: {
cj20q44v100003j5wglj6c5h8: {
url: 'https://www.example.org/image0',
name: 'image0'
},
cj20q44vg00013j5whajs12ed: {
url: 'https://www.example.org/image1',
name: 'image1'
}
};
解决方案
解决此问题是改变 processStrategy
回调中的输入值,给它一个 uid
属性。
Solution
A work around for this is to mutate the input value in the processStrategy
callback, giving it an uid
attribute.
const getUid = value => {
if (!Object.prototype.hasOwnProperty.call(value, 'uid')) value.uid = uuid.v4();
return {...value};
};
const image = new Schema('images', { processStrategy: getUid, idAttribute: 'uid'});
你现在正在改变这个值,所以很糟糕,但 idAttribute
选项使用输入值,而不是处理后的值。
You're mutating the value now, so that sucks, but the idAttribute
option uses the input value, not the processed value.
或者,您可以改变 idAttribute <中的值/ code>回调,然后你不会将
uid
字段添加到输出值。
Alternatively, you could mutate the value in the idAttribute
callback, then you would not add the uid
field to the output value.
旁注:我建议使用 cuid
npm包而不是 uuid
sidenote: I would recommend using the cuid
npm package instead of uuid
这篇关于Normalizr - 如何生成与父实体相关的slug / id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!