1

我的理解是 usingserializeIds: '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,但会添加根并侧载客户,这是我不想要的。

4

1 回答 1

3

您遇到了一些奇怪的行为,如何serializeIdsembed.

embed: true首先,当您只是尝试禁用根时,为什么需要设置令人困惑。原因是因为embed默认为false,所以如果你删除root并尝试包含相关资源,Mirage不知道将它们放在哪里。这是一个令人困惑的选项组合,而 Mirage 确实应该有不同的“模式”来考虑这一点。

其次,似乎当embed为真时,Mirage 基本上忽略了该serializeIds选项,因为它认为您的资源将始终被嵌入。(这里的想法是外键用于单独获取相关资源,但是当它们嵌入时,它们总是一起出现。)这也很混乱,不需要这样。我在 Mirage 中打开了一个跟踪问题来帮助解决这些问题。

至于今天的你,解决这个问题的最好方法是保留roottrue 和embedfalse,它们都是默认值,这样才能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

查看这个 REPL 示例并尝试向每个 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 感到抱歉!

于 2020-04-06T13:58:01.770 回答