🐡
【Vue.js + Rails API】Railsでアソシエーションを組んだデータをVueで表示する方法
Vue.jsとRails APIモードを使ってSPAのクイズアプリを作っています。そのなかで、Rails側でアソシエーションを組んだデータをVue側で表示する方法がわからなかったので調べながら実装しました。
初めに試したこと
questionsテーブルとchoicesテーブルが1対多のアソシエーションを組んでいます。はじめはそれぞれにallメソッドを使い、そのjsonデータをaxiosを使ってVueに通信していました。
questions_controller.rb
def index
questions = Question.all
render json: questions
end
choices_controller.rb
def index
choices = Choice.all
render json: choices
end
しかしそれぞれを別で取得しても、Railsでアソシエーションを組んだ際に使える、question.choicesのような使い方はVueでできません。
Questions.vue
<table v-for="question in questions" :key="question.id">
<tr>問題</tr>
<tr>
{{ question.id}}
{{ question.content }}
<p>回答</p>
<p v-for="choice in question.choices" :key="choice.id">
{{ choice.content }} // question.choicesは使えないので表示されない!!
</p>
</tr>
</table>
これを解決するために、 Rails側でquestions取得時にchoicesをjsonデータに含める 必要があります。
includeを使って、複数のテーブルをjsonデータに含める
choicesコントローラは削除して、以下のように追記します。
questions_controller.rb
def index
questions = Question.all
render json: questions, include: [:choices]
end
これで、questionsテーブルのなかにアソシエーションを組んだchoicesも含まれたjsonデータがレンダリングされます。(イメージは以下。)
[
{
id: 1,
content: 'jsの正式名称は?',
choices: [
{ id: 1, name: 'javascript' },
{ id: 2, name: 'jajascript' },
{ id: 3, name: 'jasjas' },
{ id: 4, name: 'java' }
]
},
{
id: 2
....
}
]
参考までに、実際のjsonデータが以下です。(わかりにくい)
これで先程のVueファイルのように、question.choicesが使えるようになりました。
まとめ
Rails側でアソシエーションを組んだテーブルも含めたjsonデータをVueに通信することで、Railsのhtml.erbの記法のように書くことができました。今後もVue.js + Rails APIでの困りごとを記事にしていきますので、ご質問あればコメントまで。
参考記事
Discussion