Search code examples
ruby-on-railsrubyruby-on-rails-4active-model-serializers

Rails 4 AMS with three nested models


I am using active_model_serializers gem for the first time. Version which I'm using is 0.10.2

I have three models with associations like this:

class Song < ActiveRecord::Base
    has_many :questions
end

class Question< ActiveRecord::Base
    belongs_to :song
    has_many :answers
end

class Answer< ActiveRecord::Base
    belongs_to :question
end

I've generated three serializers like this:

class SongSerializer < ActiveModel::Serializer
   attributes :id, :audio, :image

   has_many :questions
end

class QuestionSerializer < ActiveModel::Serializer
   attributes :id, :text

   belongs_to :song
   has_many :answers
end

class AnswerSerializer < ActiveModel::Serializer
   attributes :id, :text

   belongs_to :question
end

but unfortunately my json response doesn't show me the question's answers, but songs and questions are showing.

after some googling I tried to add ActiveModelSerializers.config.default_includes = '**' or from documentation like this:

 class Api::SongsController < ApplicationController
    def index
        songs = Song.all

        render json: songs, include: '**' #or with '*'
    end
 end

but this led me to stack level too deep error

So what should I do in order to get json response to looks like this -

  {
  "id": "1",
  "audio": "...",
  "image": "...",
  "questions": [
    {
      "id": "1",
      "text": ".....",
      "answers": [
        {
          "id": "1",
          "text": "...."
        },
        {
          "id": "2",
          "text": "..."
        }
      ]
    },
    {
      "id": "2",
      "text": "....."
    }
  ]
}

because simply adding associations like I would do in models are not helping for the third association.

Any help would be appreciated!


Solution

  • So finally after some more searching I found solution which worked. I had to add to my controller include with nested models.

    class Api::SongsController < ApplicationController
        def index
            songs = Song.all
    
            render json: songs, include: ['questions', 'questions.answers']
        end
     end
    

    And it worked like a charm!