Есть ли способ показать связанные идентификаторы модели без боковой загрузки или встраивания данных - PullRequest
0 голосов
/ 02 апреля 2020

Насколько я понимаю, использование 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, но добавляет root и загружает клиента, что мне не нужно.

1 Ответ

1 голос
/ 06 апреля 2020

Вы столкнулись со странным поведением того, как serializeIds взаимодействует с embed.

Во-первых, сбивает с толку, почему вам нужно установить embed: true, когда вы просто пытаетесь отключить root. Причина в том, что embed по умолчанию имеет значение false, поэтому, если вы удалите root и попытаетесь включить связанные ресурсы, Mirage не будет знать, где их разместить. Это запутанная комбинация опций, и у Mirage действительно должны быть разные «режимы», которые учитывают это.

Во-вторых, кажется, что когда embed истинно, Mirage в основном игнорирует опцию serializeIds, так как он думает, что ваши ресурсы всегда будут встроены. (Идея заключается в том, что внешний ключ используется для извлечения связанных ресурсов по отдельности, но когда они встроены, они всегда объединяются.) Это также сбивает с толку и не должно иметь место. Я открыл отслеживающую проблему в Мираже, чтобы помочь решить эти проблемы.

Что касается вас сегодня, лучший способ решить эту проблему - оставить root равным true и 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 и вставьте следующую конфигурацию на вкладку «Конфигурация», затем попробуйте сделать запрос на каждый 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!

...