【rails】複数のjsonデータを返す方法
発生経緯
railsアプリを作る時、Vue.jsを使うと基本的にrailsのデータはAPIで返すことになる。 ということは最後の出力をjson形式で返すことになるわけだが、ここでかなりつまづいたので忘れないようにメモしておく。
単体jsonデータの場合
class QuestionsController < ApplicationController def index @question = Question.new @questions = Question.all.order(created_at: "DESC") respond_to do |format| format.html format.json end end end
QuestionテーブルはUserテーブルと紐づいており、Questions(多):User(1)の関係になっている。この時 index.json.jbuilder
を使うとこんな感じになる。
json.array! @questions, :title, :content, :user
一応これで@questionsに関連したUserもjson形式で送ることはできた。が、これだけのためにjbuilderを使うのはもったいない。
そこで、Controllerの方でまとめてみる。
class QuestionsController < ApplicationController def index @question = Question.new questions = Question.all.order(created_at: "DESC") respond_to do |format| format.html format.json { render json: questions, include: [:user] } end end end
include
を使うことで、関連したテーブルのデータも送ることができるようになる。jsonの中身を確認すべくhtml端子を .json
にしてみる。
[{"id":1,"title":"hoge","content":"huga","user_id":1,"created_at":"2019-10-14T10:33:14.247+09:00","updated_at":"2019-10-14T10:33:14.247+09:00","user":{"id":1,"email":"hoge@gmail.com","created_at":"2019-10-13T16:58:27.516+09:00","updated_at":"2019-10-13T16:58:27.516+09:00","name":"foo"}}]
ちょっと見辛いが、questionのuser_idに紐づいたUserのデータが一緒に入っているのがわかる。
複数のjsonデータの場合
では、showメソッドでquestionに紐づいたanswerも一緒に送るにはどうすれば良いか?
class QuestionsController < ApplicationController def show @question = Question.find(params[:id]) @answers = Answer.where(question_id: params[:id]).order(created_at: "DESC") @answer = Answer.new respond_to do |format| format.html format.json end end end
ここで得たいのはquestionのデータとanswersのデータ。
ひとまず show.json.jbuilder
に書いてみる。
json.question @question, :title, :content, :user json.answers do json.array! @answers, :text, :user end
複数の時も上のようにcontrollerにまとめるには .to_json
を使うとできなくはないが、Vueで受け取ったデータに \
が死ぬほど入ってきた…
まとめ
単体jsonデータはcontrollerにまとめることができたけど、複数のデータのまとめかたがいまいちわからなかった…ここは忘れずに改善する必要がある。