🐡

【Vue.js + Rails API】Railsでアソシエーションを組んだデータをVueで表示する方法

2022/03/01に公開

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での困りごとを記事にしていきますので、ご質問あればコメントまで。

参考記事

https://yasagori-programing.hatenablog.jp/entry/2019/10/14/142912

Discussion