1

I am using Rails 4, and I have some simple models as follow:

class Question < ActiveRecord::Base
  # columns (id, text)
  has_many :answers
end

class Answer < ActiveRecord::Base
  # columns (id, text, next_question_id)
  belongs_to :question
end

You can see that an answer has a next_question_id column, which will be used to look up another question. I want to generate a tree-structure json like this:

{
  "text": "This is question 1",
  "answers": [
    {
      "text": "This is answer a",
      "next_question": {
        "text": "This is question 2",
        "answers": [
          {
            "text": "This is answer c",
            "next_question":
          }
        ]
      }
    },
    {
      "text": "This is answer b",
      "next_question": {
        "text": "This is question 2",
        "answers": [
          {
            "text": "This is answer d",
            "next_question":
          }
        ]
      }
    }
  ]
}

How can I achieve this with JBuilder? I tried the solution here, but I cannot pass the json argument to the helper function.

Community
  • 1
  • 1
Khanetor
  • 11,595
  • 8
  • 40
  • 76

1 Answers1

2

The standard aproach for rendering trees is using a recursive partial. To implement this you'll first need to add a method to your Answer model like this.

def next_question
  Question.find(next_question_id) if next_question_id  
end

(hint: alternetively you could just set a belongs_to :next_question, class_name: Question association on your Answer model)

Then you create a partial like _question.json.jbuilder that goes like this:

json.(question,:id, :text)
json.answers question.answers do |answer|
  json.(answer, :id, :text)
  json.partial!(:question, question: answer.next_question) if answer.next_question
end

Then in the controller you take the first question in your survey and put it in say the @first_question variable.

And the last thing: in your view you write

json.partial! :question, question: @first_question
Almaron
  • 4,127
  • 6
  • 26
  • 48
  • I think we are heading in the right direction. I think in the second line of the partial jbuilder file, you want `json.answers question.answers do |answer|`. – Khanetor Mar 17 '15 at 15:10
  • I think that we should change `json.partial! :question, ...` to `json.partial! 'question, ...`. Could you confirm that before I mark this answer accepted? Thanks Almaron! – Khanetor Mar 17 '15 at 15:19
  • Yea, I missed the collection, fixed that. You can use either a symbol or a string as a partial name as long as the partial is in the safe directory as the initial view. – Almaron Mar 17 '15 at 16:03
  • In my case, when I use a symbol for the partial, it does not work. It says that the symbol is not a compatible ActiveRecord object. – Khanetor Mar 17 '15 at 16:04