我们的应用程序主要是使用模型属性的下划线创建的,因此我们很难完全实现mirage。当我们试图在模型中包含一个被引用为下划线属性的相关模型时,我们会收到以下错误:
Mirage: You tried to include 'dasherized-attribute-name' with model:example(1) but no association named 'dasherizedAttributeName' is defined on the model
模型/工厂设置如下:
app/models/example.js:
import { belongsTo } from 'ember-data/relationships';
import Model from 'ember-data/model';
export default Model.extend({
dasherized_attribute_name: belongsTo('attribute', { inverse: 'examples' }),
});应用程序/模型/属性.js:
import { hasMany } from 'ember-data/relationships';
import Model from 'ember-data/model';
export default Model.extend({
examples: hasMany('example', {
inverse: 'dasherized_attribute_name',
}),
});app/mirage/factories/example.js:
import { Factory, association } from 'ember-cli-mirage';
export default Factory.extend({
dasherized_attribute_name: association(),
});app/mirage/serializers/application.js:
import { JSONAPISerializer } from 'ember-cli-mirage';
import { pluralize } from 'ember-inflector';
import { underscore } from '@ember/string';
export default JSONAPISerializer.extend({
alwaysIncludeLinkageData: true,
keyForAttribute(key) {
return underscore(key);
},
keyForRelationship(key) {
// underscoring this value does nothing
return key;
},
payloadKeyFromModelName(modelName) {
return underscore(pluralize(modelName));
},
});示例测试:
import { module, test } from 'qunit';
import hbs from 'htmlbars-inline-precompile';
import { render } from '@ember/test-helpers';
import { setupRenderingTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
module('Integration | Component | example', (hooks) => {
setupRenderingTest(hooks);
setupMirage(hooks);
hooks.beforeEach(async function () {
this.store = this.owner.lookup('service:store');
const serverExample = this.server.create('example');
const example = await this.store.findRecord(
'example',
serverExample.id,
{ include: 'dasherized_attribute_name' }
);
this.set('example', example);
});
test('it renders', async (assert) => {
await render(hbs`
{{component
example=example
}}
`);
assert.dom('[data-test-example]').exists();
});
});我发现这是非常令人困惑和不直观的。我们的属性是蛇形大小写,错误表明我们正在尝试包含dasherized属性,但它最终在模型上查找驼峰大小写的属性?当然,将模型/工厂属性更改为驼峰式大小写可以解决这个问题,但对于我们的应用程序来说,考虑到属性的绝对数量,这并不一定可行。我已经尝试了序列化程序文档中引用的每一个钩子,试图处理这种情况,但就是找不到这些转换实际发生的位置。任何帮助都将不胜感激。
发布于 2019-12-15 01:49:22
很抱歉你正在苦苦挣扎,我们真的应该在网站的某个地方添加一个指南来解释这一点!
我可以帮你澄清。当我第一次写幻影时,我们实际上做了你的直觉所建议的:将幻影的模型和关系与你的API约定相匹配。
事实证明,这是有限的和令人困惑的。幻影真正需要的是一个序列化器层,它将独立于数据层负责数据的形状。这样,数据层可以对主机应用程序的数据+关系做出更多假设,例如,外键存储在哪里。
这就是为什么我们在幻影中引入了序列化程序。串行化器将传入的有效负载转换为幻影能够理解的“标准”格式,并将传出的有效负载转换为您的API发送的格式(这也是您的Ember应用程序期望的格式)。因此,为了回答您的问题,序列化程序是您想要解决此问题的层。
对于你来说,有一个ActiveModelSerializer可能是一个很好的起点,因为它已经强调了属性。取决于你的后端,这可能会起作用,或者你可以自己实现一个序列化程序。配置序列化程序应该是一次性的,应用程序范围内的事情,假设您的生产API在某种程度上是一致的。例如,您可以使用各种keyFor*方法将幻影模型+关系camelCase约定转换为下划线。如果你想看一个例子,你可以看看the source for ActiveModelSerializer。
最后一部分是normalize()方法,它接受传入的请求并将其转换为JSON:API格式,因此Mirage知道在哪里查找属性和关系。同样,大多数应用程序应该能够扩展现有的序列化程序之一,因此您不必自己编写此程序。但这取决于您的后端API格式。normalize()方法可以让幻影的速记和normalizedRequestAttrs等助手处理Ember应用程序的请求数据。
希望这能为这个问题提供一些启发,你实际上可以看到2015年我第一次思考这个问题时的一篇更老的博客帖子here。如果您在配置序列化程序时仍然有问题,请在幻影存储库上打开一个新问题,或者打开一个新的Stack Overflow问题,我会尽我最大的努力来回答它!
https://stackoverflow.com/questions/59313746
复制相似问题