Есть ли способ показать идентификаторы связанных моделей без загрузки или встраивания данных
Насколько я понимаю, использование serializeIds: 'always'
предоставит мне эти данные, но это не так.
Вот чего я жду:
{
id="1"
title="some title"
customerId="2"
}
Вместо этого я получаю следующий результат:
{
id="1"
title="some title"
}
Мой код выглядит примерно так:
import {
Server,
Serializer,
Model,
belongsTo,
hasMany,
Factory
} from "miragejs";
import faker from "faker";
const ApplicationSerializer = Serializer.extend({
// don't want a root prop
root: false,
// true required to have root:false
embed: true,
// will always serialize the ids of all relationships for the model or collection in the response
serializeIds: "always"
});
export function makeServer() {
let server = newServer({
models: {
invoice: Model.extend({
customer: belongsTo()
}),
customer: Model.extend({
invoices: hasMany()
})
},
factories: {
invoice: Factory.extend({
title(i) {
return `Invoice ${i}`;
},
afterCreate(invoice, server) {
if (!invoice.customer) {
invoice.update({
customer: server.create("customer")
});
}
}
}),
customer: Factory.extend({
name() {
let fullName = () =>
`${faker.name.firstName()} ${faker.name.lastName()}`;
return fullName;
}
})
},
seeds(server) {
server.createList("invoice", 10);
},
serializers: {
application: ApplicationSerializer,
invoice: ApplicationSerializer.extend({
include: ["customer"]
})
},
routes() {
this.namespace = "api";
this.get("/auth");
}
});
}
Изменение конфигурации на root: true, embed: false,
обеспечивает правильный вывод в invoice
модели, но добавляет корень и загружает неопубликованные версии клиента, что мне не нужно.
1 ответ
Вы столкнулись со странным поведением, как serializeIds
взаимодействует с embed
.
Во-первых, непонятно, зачем нужно устанавливать embed: true
когда вы просто пытаетесь отключить рут. Причина в том, чтоembed
по умолчанию установлено значение false, поэтому, если вы удалите корень и попытаетесь включить связанные ресурсы, Mirage не знает, где их разместить. Это запутанное сочетание опций, и Mirage действительно должен иметь разные "режимы", которые это учитывают.
Во-вторых, кажется, что когда embed
правда, Мираж в основном игнорирует serializeIds
вариант, так как он думает, что ваши ресурсы всегда будут встроены. (Идея здесь в том, что внешний ключ используется для получения связанных ресурсов по отдельности, но когда они встроены, они всегда объединяются.) Это также сбивает с толку и не обязательно так. Я открыл проблему отслеживания в Mirage, чтобы помочь решить эти проблемы.
Что касается вас сегодня, лучший способ решить эту проблему - это оставить root
к истине и embed
false, которые являются значениями по умолчанию, так что serializeIds
работает правильно, а затем просто напишите свой serialize()
функция удаления ключа для вас:
const ApplicationSerializer = Serializer.extend({
// will always serialize the ids of all relationships for the model or collection in the response
serializeIds: "always",
serialize(resource, request) {
let json = Serializer.prototype.serialize.apply(this, arguments);
let root = resource.models ? this.keyForCollection(resource.modelName) : this.keyForModel(resource.modelName)
return json[root];
}
});
Вы сможете проверить это на обоих /invoices
а также /invoices/1
.
Посетите WIP Inspector и вставьте следующую конфигурацию на вкладку Config, затем попробуйте сделать запрос для каждого URL-адреса.
import {
Server,
Serializer,
Model,
belongsTo,
hasMany,
Factory,
} from "miragejs";
import faker from "faker";
const ApplicationSerializer = Serializer.extend({
// will always serialize the ids of all relationships for the model or collection in the response
serializeIds: "always",
serialize(resource, request) {
let json = Serializer.prototype.serialize.apply(this, arguments);
let root = resource.models ? this.keyForCollection(resource.modelName) : this.keyForModel(resource.modelName)
return json[root];
}
});
export default new Server({
models: {
invoice: Model.extend({
customer: belongsTo(),
}),
customer: Model.extend({
invoices: hasMany(),
}),
},
factories: {
invoice: Factory.extend({
title(i) {
return "Invoice " + i;
},
afterCreate(invoice, server) {
if (!invoice.customer) {
invoice.update({
customer: server.create("customer"),
});
}
},
}),
customer: Factory.extend({
name() {
return faker.name.firstName() + " " + faker.name.lastName();
},
}),
},
seeds(server) {
server.createList("invoice", 10);
},
serializers: {
application: ApplicationSerializer,
},
routes() {
this.resource("invoice");
},
});
Надеюсь, это проясняет ситуацию + извините за запутанные API!