【Rails API】複数テーブルをincludeし特定のカラムを指定してレスポンスデータを作る

RailsでAPIを作成するときに、複数のテーブルから特定のカラムの値だけをレスポンスデータに含める方法が分からなかったので、備忘録としてまとめます。

バージョン
  • Ruby 3.2.2
  • Rails 7.1.2
記事の信頼性
  • ぼくは独学で未経験から従業員300名以上の自社開発企業へ転職しました。
  • 実務ではVue.jsとRailsを毎日書いています。
  • 初心者や駆け出しエンジニアがつまづくポイントも身をもってよく理解しています。
目次

問題

ぼくは今クイズアプリを作っており、特定のクイズを画面に表示するために以下のレスポンスデータを用意する必要がありました。

{
  "quiz":{
    "id":1,
    "quiz_category_id":1,
    "content":"ここにクイズの問題文が入ります。",
    "explanation":"ここにクイズの解説が入ります。",
    "created_at":"2024-01-22T23:35:31.014Z",
    "updated_at":"2024-01-22T23:35:31.014Z",
    "quiz_choices":[
      {
        "id":1,
        "content":"ここに1つ目の選択肢が入ります。"
      },
      {
        "id":2,
        "content":"ここに2つ目の選択肢が入ります。"
      },
      {
        "id":3,
        "content":"ここに3つ目の選択肢が入ります。"
      },
      {
        "id":4,
        "content":"ここに4つ目の選択肢が入ります。"
      }
    ],
    "quiz_category":{
      "id":1,
      "title":"クイズのカテゴリ名が入ります。",
      "description":"カテゴリの詳細内容が入ります。"
      }
    },
  }

このケースの場合、ベースとなるQuizテーブルに加えて親テーブルのQuizCategoryと子テーブルのQuizChoiceからもデータを取得して含める必要があります。

これを実現するために最初は次のように記述していました。

    render json: {
      quiz: quiz.as_json(include: [:quiz_category, :quiz_choices])
    }

QuizCategoryQuizChoiceの全てのカラムの値をレスポンスデータに含めて良いのなら、↑のように書けば問題ありません。

しかし今回の場合、QuizCategoryテーブルからはid, title, descriptionカラム、QuizChoiceテーブルからはid, contentカラム以外の値は不要です。

必要なカラムだけを指定したかったのですが、そのやり方が分からず時間をかけてしまいました、、。

解決方法

結論として、次のように書けばOKです。

render json: {
  quiz: quiz.as_json(
    include: {
      quiz_category: {
        only: [:id, :title, :description]
      },
      quiz_choices: {
        only: [:id, :content]
      },
    }
  ),
}

includeオプションで関連づけた各テーブル毎に、さらにonlyオプションで必要なカラムを指定することで、狙ったカラムの値だけをレスポンスデータに含めることができました!

おわりに

最初は混乱しましたが、一度理解してしまえばとても便利に感じられますね。

参考文献
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

未経験でSESから従業員300名以上の自社開発企業に転職しました。業務や個人開発で直面した問題や、転職・学習の経験を発信していきます。

コメント

コメントする

目次