ember.js Mirage服务器获取数据,但POST失败

zynd9foi  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(172)

我有幻影模型:

// mirage/models/country.js
import { Model, belongsTo, hasMany } from 'miragejs';

export default Model.extend({
    name: '',
    iso3166_1_alpha3: '',
    capitol_city: belongsTo('city', {inverse: null}),
    cities: hasMany('city', {inverse: 'country'})
});

以及:

// mirage/models/city.js
import { Model, belongsTo } from 'miragejs';

export default Model.extend({
    name: '',
    country: belongsTo('country', {inverse: 'cities'})
});

以及串行器:

// mirage/serializers/application.js
import { camelize, capitalize, underscore } from '@ember/string';
import { JSONAPISerializer } from 'miragejs';

export default class ApplicationSerializer extends JSONAPISerializer
{
    alwaysIncludeLinkageData = true;

    keyForAttribute(attr) {
        return underscore(attr);
    };
    keyForRelationship(modelName) {
        return underscore(modelName);
    };
    typeKeyForModel(model) {
        return capitalize(camelize(model.modelName));
    };
};

当我运行测试时:

import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';

module('Unit | Mirage | mirage models', function (hooks) {
  setupTest(hooks);
  setupMirage(hooks);

  test('it retrieves the country', async function (assert) {
    const server = this.server;
    let city = server.create('city', { id: '1', name: 'Paris' });

    server.create(
        'country',
        {
            id: 'FR',
            name: 'France',
            iso3166_1_alpha3: 'FRA',
            capitol_city: city
        }
    );

    let response = await fetch('/api/countries')
    assert.strictEqual(response.status, 200, "Should have created the model");
    let json = await response.json();
    assert.deepEqual(
        json,
        {
            data: [
                {
                    type: 'Country',
                    id: 'FR',
                    attributes: {
                        name: 'France',
                        iso3166_1_alpha3: 'FRA',
                    },
                    relationships: {
                        capitol_city: {data: {type: 'City', id: '1'}},
                        cities: {data: []},
                    }
                }
            ]
        }
    )
  });

  test('it creates the country', async function (assert) {
    const server = this.server;
    server.create('city', { id: '1', name: 'Paris' });

    let response = await fetch(
        '/api/countries',
        {
            method: 'POST',
            headers: {'Countent-Type': 'application/json'},
            body: JSON.stringify(
                {
                    data: {
                        id: 'FR',
                        type: 'Country',
                        attributes: {
                            iso3166_1_alpha3: 'FRA',
                            name: 'France',

                        },
                        relationships: {
                            capitol_city: { data: { type: 'City', id: '1'} },
                            cities: { data: [{ type: 'City', id: '1'}] }
                        }
                    }
                }
            )
        }
    );

    console.log((await response.json()).message);
    assert.strictEqual(response.status, 201, "Should have created the model");
  });
});

第一个通过,第二个失败,并显示消息:

Mirage: You're passing the relationship 'capitol_city' to the 'country' model via a POST to '/api/countries', but you did not define the 'capitol_city' association on the 'country' model.

如何让Mirage识别模型上的capitol_city属性?

30byixjq

30byixjq1#

Mirage对属性的格式很固执,希望属性采用camelCase(而不是snake_case)。
不幸的是Ember CLI Mirage model relationships documentation没有提到这个期望,所有的例子都使用单字属性。更不幸的是,Mirage将使用snake_case属性来处理简单的GET请求和通过API直接创建模型;只有当您向POST/PUT/PATCH模型请求进入服务器时,它才会失败,并且消息将(令人困惑地)引用已定义的snake case属性。(请参阅Mirage源代码了解失败的位置。)
若要解决此问题,请将属性转换为驼峰式:

// mirage/models/country.js
import { Model, belongsTo, hasMany } from 'miragejs';

export default Model.extend({
    name: '',
    iso31661Alpha3: 0,
    capitolCity: belongsTo('city', {inverse: null}),
    cities: hasMany('city', {inverse: 'country'})
});

并在测试中改变它:

import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';

module('Unit | Mirage | mirage models', function (hooks) {
  setupTest(hooks);
  setupMirage(hooks);

  test('it retrieves the country', async function (assert) {
    const server = (this as any).server;
    let city = server.create('city', { id: '1', name: 'Paris' });

    server.create(
        'country',
        {
            id: 'FR',
            name: 'France',
            iso31661Alpha3: 'FRA',
            capitolCity: city
        }
    );

    let response = await fetch('/api/countries')
    assert.strictEqual(response.status, 200, "Should have created the model");
    let json = await response.json();
    console.log(JSON.stringify(json));
    assert.deepEqual(
        json,
        {
            data: [
                {
                    type: 'Country',
                    id: 'FR',
                    attributes: {
                        name: 'France',
                        iso3166_1_alpha3: 'FRA',
                    },
                    relationships: {
                        capitol_city: {data: {type: 'City', id: '1'}},
                        cities: {data: []},
                    }
                }
            ]
        }
    )
  });

  test('it creates the country', async function (assert) {
    const server = (this as any).server;
    let city = server.create('city', { id: '1', name: 'Paris' });

    let response = await fetch(
        '/api/countries',
        {
            method: 'POST',
            headers: {'Countent-Type': 'application/json'},
            body: JSON.stringify(
                {
                    data: {
                        id: 'FR',
                        type: 'Country',
                        attributes: {
                            iso3166_1_alpha3: 'FRA',
                            name: 'France',

                        },
                        relationships: {
                            capitol_city: { data: { type: 'City', id: '1'} },
                            cities: { data: [{ type: 'City', id: '1'}] }
                        }
                    }
                }
            )
        }
    );

    console.log((await response.json()).message);
    assert.strictEqual(response.status, 201, "Should have created the model");
  });
});

但是,一旦您将其转换为camel case,则iso31661Alpha3属性在输出中的格式将不正确,因此您必须手动更改country模型的序列化程序:

// mirage/serializers/country.js
import ApplicationSerializer from './application';

export default class CountrySerializer extends ApplicationSerializer
{
    keyForAttribute(attr: string) {
        switch(attr)
        {
            case 'iso31661Alpha3': return 'iso3166_1_alpha3';
            default: return super.keyForAttribute(attr);
        }
    };
};

一旦属性的大小写正确,它就会工作。

相关问题