RailsでAPIを作成するときに、複数のテーブルから特定のカラムの値だけをレスポンスデータに含める方法が分からなかったので、備忘録としてまとめます。
目次
問題
ぼくは今クイズアプリを作っており、特定のクイズを画面に表示するために以下のレスポンスデータを用意する必要がありました。
{
"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])
}
QuizCategory
とQuizChoice
の全てのカラムの値をレスポンスデータに含めて良いのなら、↑のように書けば問題ありません。
しかし今回の場合、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
オプションで必要なカラムを指定することで、狙ったカラムの値だけをレスポンスデータに含めることができました!
おわりに
最初は混乱しましたが、一度理解してしまえばとても便利に感じられますね。
コメント