首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >您试图在model:example(1)中包含'dasherized-attribute-name‘,但没有在模型上定义名为'dasherizedAttributeName’的关联

您试图在model:example(1)中包含'dasherized-attribute-name‘,但没有在模型上定义名为'dasherizedAttributeName’的关联
EN

Stack Overflow用户
提问于 2019-12-13 06:44:22
回答 1查看 324关注 0票数 2

我们的应用程序主要是使用模型属性的下划线创建的,因此我们很难完全实现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:

代码语言:javascript
复制
import { belongsTo } from 'ember-data/relationships';
import Model from 'ember-data/model';

export default Model.extend({
    dasherized_attribute_name: belongsTo('attribute', { inverse: 'examples' }),
});

应用程序/模型/属性.js:

代码语言:javascript
复制
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:

代码语言:javascript
复制
import { Factory, association } from 'ember-cli-mirage';

export default Factory.extend({
    dasherized_attribute_name: association(),
});

app/mirage/serializers/application.js:

代码语言:javascript
复制
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));
    },
});

示例测试:

代码语言:javascript
复制
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属性,但它最终在模型上查找驼峰大小写的属性?当然,将模型/工厂属性更改为驼峰式大小写可以解决这个问题,但对于我们的应用程序来说,考虑到属性的绝对数量,这并不一定可行。我已经尝试了序列化程序文档中引用的每一个钩子,试图处理这种情况,但就是找不到这些转换实际发生的位置。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 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问题,我会尽我最大的努力来回答它!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59313746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档