フィクスチャ

Mirageでは、フラットなフィクスチャファイルを使用してデータベースにデータを投入することもできます。

一般的には、モックデータをより保守しやすくするために、ほとんどの場合、ファクトリを使用することをお勧めします。しかし、フィクスチャデータが理にかなう場合もあります。

フィクスチャは、次のことを実現するための従来の方法にすぎません。

import { createServer } from "miragejs"

createServer({
  seeds(server) {
    server.db.loadData({
      countries: [
        { id: 1, name: "China" },
        { id: 2, name: "India" },
        { id: 3, name: "United States" },
      ],
    })
  },
})

フィクスチャを使用して同じことをどのように行うことができるかを見てみましょう。

基本的な使用方法

フィクスチャデータは、fixturesキーを使用してMirageサーバー定義に渡すことができます。

import { createServer } from "miragejs"

createServer({
  fixtures: {
    countries: [
      { id: 1, name: "China" },
      { id: 2, name: "India" },
      { id: 3, name: "United States" },
    ],
  },
})

seeds関数が定義されていない限り、このデータはMirageのデータベースに初期データとして自動的にロードされます。

seeds関数が定義されている場合、Mirageはファクトリを使用してデータを投入することを想定しています。

import { createServer } from "miragejs"

createServer({
  fixtures: {
    countries: [
      { id: 1, name: "China" },
      { id: 2, name: "India" },
      { id: 3, name: "United States" },
    ],
  },

  seeds(server) {
    // Fixtures won't be loaded automatically, because this function is defined

    server.create("post")
  },
})

しかし、デフォルトのシナリオでserver.loadFixturesを呼び出すことで、ファクトリと併用してフィクスチャを使用できます。

import { createServer } from "miragejs"

createServer({
  fixtures: {
    countries: [
      { id: 1, name: "China" },
      { id: 2, name: "India" },
      { id: 3, name: "United States" },
    ],
  },

  seeds(server) {
    // Load all fixture data into the development db
    server.loadFixtures()

    // Also create some db data using factories
    server.create("post")
  },
})

通常、フィクスチャは別々のファイルに抽出されます。国のフィクスチャデータを独自のfixtures/countries.jsファイルに入れ、配列としてエクスポートできます。

// mirage/fixtures/countries.js
export default [
  { id: 1, name: "China", largestCity: "Shanghai" },
  { id: 2, name: "India", largestCity: "Mumbai" },
  { id: 3, name: "United States", largestCity: "New York City" },
  { id: 4, name: "Indonesia", largestCity: "Jakarta" },
  { id: 5, name: "Pakistan", largestCity: "Karachi" },
  { id: 6, name: "Brazil", largestCity: "São Paulo" },
  { id: 7, name: "Nigeria", largestCity: "Lagos" },
  { id: 8, name: "Bangladesh", largestCity: "Dhaka" },
  { id: 9, name: "Russia", largestCity: "Moscow" },
  { id: 10, name: "Mexico", largestCity: "Mexico City" },
]

これで、それをインポートしてサーバー定義に渡すことができます。

import { createServer } from "miragejs"
import countries from "./fixtures/countries"

createServer({
  fixtures: {
    countries,
  },
})

多くのチームは、このように特定のシードデータを個別のフィクスチャファイルとして保存することを有用だと考えています。

属性のフォーマット

フィクスチャデータはMirageのデータベースに直接読み込まれるため、複数の単語からなる属性にはすべてcamelCaseを使用することが重要です。(Mirageは、外部キーの識別などの設定を避けるためにcamelCasing規則を使用しています。)

本番APIフォーマットでcamelCaseを使用していない場合でも心配しないでください。シリアライザーレイヤーでMirageのAPIフォーマットをカスタマイズできます。

loadFixtures ヘルパー

上記のように、Mirageはフィクスチャとデフォルトのシナリオの両方を検出した場合、フィクスチャデータを自動的にロードしません。

開発中にデータベースにフィクスチャをロードするには、デフォルトのシナリオでserver.loadFixturesを呼び出します。

seeds(server) {
  server.loadFixtures()
}

server.loadFixtures()はすべてのフィクスチャをロードします。loadFixturesにフィクスチャ名の引数リストを渡すことで、フィクスチャを選択的にロードできます。

import { createServer, Model } from "miragejs"
import cities from "./fixtures/cities"
import countries from "./fixtures/countries"
import users from "./fixtures/users"

createServer({
  models: {
    country: Model,
    city: Model,
    user: Model,
  },

  fixtures: {
    countries: countries,
    cities: cities,
    users: users,
  },

  seeds(server) {
    // only load the countries and cities fixtures
    server.loadFixtures("countries", "cities")
  },
})

デフォルトのシナリオと同様に、テスト中はフィクスチャは無視されます。テストでフィクスチャデータを読み込む場合は、server.loadFixturesを呼び出すことができます。

test("I can see the countries", async function (assert) {
  server.loadFixtures("countries")

  await visit("/")

  assert.dom("option.country").exists({ length: 100 })
})

リレーションシップ

フィクスチャを使用してリレーションシップを作成するための特別なAPIはありません。Mirageが外部キーを使用してリレーションシップを接続する方法を理解するだけです。

これらのモデルがあるとしましょう。

import { createServer, Model } from "miragejs"

createServer({
  models: {
    user: Model,

    post: Model.extend({
      author: belongsTo("user"),
    }),
  },
})

ORMを使用すると、2つの関連モデルを作成できます。

let chris = schema.users.create({ name: "Chris Garrett" })

schema.posts.create({
  author: chris,
  title: "Coming Soon in Ember Octane",
})

その後、Mirageのデータベースを見てみると、このデータが表示されます。

// server.db.dump()

{
  "users": [{ "id": "1", "name": "Chris Garrett" }],
  "posts": [
    { "id": "1", "authorId": "1", "title": "Coming Soon in Ember Octane" }
  ]
}

ご覧のとおり、Mirageは投稿にauthorId外部キーを追加しました。 belongsTo外部キーの規則は次のとおりです。

belongsToForeignKey = `${relationshipName}Id`

この場合、投稿はUserモデルを指す関係であるにもかかわらず、authorIdを取得します。モデルは同じタイプのモデルを指す複数の関係を持つことができるため、モデル名ではなく関係名が常に使用されます。

上記のデータベースダンプを見ると、フィクスチャのみを使用して同じ関係グラフを再現するには、データがそれに一致する必要があります。

import { createServer, Model } from "miragejs"

createServer({
  models: {
    user: Model,

    post: Model.extend({
      author: belongsTo("user"),
    }),
  },

  fixtures: {
    users: [{ id: "1", name: "Chris Garrett" }],
    posts: [{ id: "1", authorId: "1", title: "Coming Soon in Ember Octane" }],
  },
})

これらのフィクスチャがMirageにロードされると、すべてのORMメソッド、ショートハンド、シリアライザーは期待どおりに機能します。

これが双方向の関係である場合

  models: {
    user: Model.extend({
+     posts: hasMany()
    }),

    post: Model.extend({
      author: belongsTo("user"),
    }),
  },

Mirageは新しいhasMany関連付けに対して外部キーの配列を追加します。

// server.db.dump()

{
  "users": [{ "id": "1", "name": "Chris Garrett", "postIds": ["1"] }],
  "posts": [
    { "id": "1", "authorId": "1", "title": "Coming Soon in Ember Octane" }
  ]
}

hasMany関係外部キーの規則は次のとおりです。

hasManyForeignKey = `${singularize(relationshipName)}Ids`

すべての関連付けには独自のキーがあります。なぜなら、Mirageは任意の一方向関係をサポートしているからです。上記の場合のように、2つの関連付けがお互いの逆である場合、ORMメソッドを使用する限り、Mirageは各モデルのキーを同期状態に保ちます。

ご覧のように、外部キーを維持し、それらを複数のフィクスチャファイル間で同期させることはやや複雑になる可能性があります。そのため、Mirageでは、ほとんどのデータ作成にファクトリを使用することを推奨しています。

それでも、フィクスチャは特定の状況で非常に役立つことがあるため、ツールボックスに入れておくのに適したツールです。


次に、このガイドのセクションを締めくくりとして、シリアライザについて学習します。シリアライザを使用すると、Mirageがアプリへの応答としてデータを送信する前に、データのフォーマットをカスタマイズできます。