[GraphQL]1対多のリレーションをAPIに反映する

# 初めに（Qiita版）

この記事は[私のブログ](https://ogutip.mixh.jp/wp/2019/06/01/graphql1%E5%AF%BE%E5%A4%9A%E3%81%AE%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92api%E3%81%AB%E5%8F%8D%E6%98%A0%E3%81%99%E3%82%8B/)を移植したものです。
内容は同じですが、ブログの方もよろしくお願いします（Likeボタンを押してくれたら嬉しい）。

# 初めに
<p><a href="https://ogutip.mixh.jp/wp/2019/06/01/graphql/">前回の記事</a>で基本的なAPIを作成しました。<br>今度はGenreGroupとGenreの1対多のリレーションをAPIに反映しようと思います。</p>

# 現状の確認

<p>使用するのはGenreGroupモデルとGenreモデルです。<br> ※Bookモデルは今回は出番がないので省略。</p>

```Ruby:schema.rb
ActiveRecord::Schema.define(version: 2019_05_12_151517) do

  create_table "genre_groups", force: :cascade do |t|
    t.string "books_genre_id"
    t.string "books_genre_name"
  end

  create_table "genres", force: :cascade do |t|
    t.string "books_genre_id", null: false
    t.string "books_genre_name", null: false
    t.integer "genre_group_id"
  end

end
```

<p>GenreGroupとGenreは1対多の関係です。</p>

```Ruby:genre.rb&genre_group.rb
# genre.rb
class Genre &lt; ApplicationRecord
  belongs_to :genre_group
end

# genre_group.rb
class GenreGroup &lt; ApplicationRecord
  has_many :genres
end
```

<p>そして、<a href="https://ogutip.mixh.jp/wp/2019/06/01/graphql/">前回の記事</a>でGenreGroupTypeを作成しました。</p>

```Ruby:app/graphql/types/genre_group_type.rb
module Types
  class GenreGroupType &lt; Types::BaseObject
    field :id,                ID,     null: false
    field :books_genre_id,    String, null: false
    field :books_genre_name,  String, null: false
  end
end
```

<p>さらに、APIのエンドポイントである':genre_groups' fieldを作成しました。</p>

```Ruby:query_type.rb
module Types
  class QueryType &lt; Types::BaseObject
    field :genre_groups, [Types::GenreGroupType], null: false,
      description: 'ジャンルグループをすべて取得する'
    def genre_groups
      GenreGroup.all
    end
  end
end
```

<p>なお、Databaseの各テーブルには適切なレコードがすでに存在する前提です。</p>

<p>それでは、GenreGroupTypeにGenreTypeを追加していきましょう。</p>

# APIの完成予定図

<p>以下のように':genre_groups' fieldを呼び出すと、GenreGroupに紐づくGenreが一緒に取れるようにします。</p>

```Text:リクエスト
# 一見するとJsonっぽいですが、Jsonでは無いです。
query {
  genreGroups{
    booksGenreId
    booksGenreName
    genres{ # ← GenreGroupに紐づくGenreを取ってくる
      id
      booksGenreId
      booksGenreName
    }
  }
}
```


```Json:レスポンス
{
  "data": {
    "genreGroups": [
      {
        "booksGenreId": "005401",
        "booksGenreName": "芸術＆エンターテインメント",
        "genres": [
          {
            "id": "1",
            "booksGenreId": "005401001",
            "booksGenreName": "写真集"
          },
          {
            "id": "2",
            "booksGenreId": "005401002",
            "booksGenreName": "絵画集"
          }
        ]
      },
      {
        "booksGenreId": "005402",
        "booksGenreName": "小説＆文芸",
        "genres": [
          {
            "id": "3",
            "booksGenreId": "005402001",
            "booksGenreName": "推理小説"
          }
        ]
      }
    ]
  }
}
```

<p>完成予定図が見えたところで、実際に作っていきます</p>

# 実装

## GenreTypeを定義する

<p>genre_group_type.rbと同じ階層に'genre_type.rb' を定義します。</p>

```Ruby:app/graphql/types/genre_type.rb
module Types
  class GenreType &lt; Types::BaseObject
    field :id,                ID,       null: false
    field :books_genre_name,  String,   null: true
    field :books_genre_id,    String,   null: true
    field :genre_group_id,    Integer,  null: false
  end
end
```

## GenreGroupTypeに':genres' fieldを定義する

<p>GenreGroupTypeに新しく':genres'を追加します。<br> 返り値はGenreTypeのリストで、non-nullです。</p>

```Ruby:app/graphql/types/genre_group_type.rb
module Types
  class GenreGroupType &lt; Types::BaseObject
    field :id,                ID,     null: false
    field :books_genre_id,    String, null: false
    field :books_genre_name,  String, null: false

    # ↓新しく追加した':genres'
    field :genres, [GenreType], '子ジャンル', null: false
  end
end
```

<p>ファイルを保存して、ブラウザでgraphiqlを開き、Docsを確認してみてください。<br>
上記の完成予想図と同じAPIが作成されているはずです。</p>

<p>以上です、簡単ですね。</p>