I am trying to make a form for a student to take an exam (with multiple-choice questions).
Here are the relevant models:
Exam has_many :questions
has_one :grade
accepts_nested_attributes_for :questions
Question has_many :answers
accepts_nested_attributes_for :answers
Grade belongs_to :exam
belongs_to :subscription
I’m using Simple_form for my application’s forms. The form for making an exam is done and working using fields_for and some javascript (as shown in the railscast on nested forms). Now I’m trying to make the form for taking an exam.
The only inputs will be a set of radio buttons for each question. The user input will be used to calculate the score and the score will be the only information saved to the Grade model. I must admit I’m at a loss at how to make this work. Here’s what I have so far for the Grade#new view:
<%= simple_form_for [@subscription, @grade], :html => { :class => 'form-horizontal' } do |f| %>
<fieldset>
<legend>Exam for <%= @lesson.name.capitalize %></legend>
<% @questions.each do |question| %>
<%= simple_fields_for :questions do |builder| %>
<ol>
<li>
<p><%= question.text %></p>
<%= f.input :answer, :collection => question.answers, :as => :radio_buttons %>
</li>
</ol>
<% end %>
<% end %>
<div class="form-actions">
<%= f.submit "Submit Exam", :class => "btn btn-primary" %>
<%= link_to "Cancel", lesson_exam_path(@lesson, @exam), :class=>"btn" %>
</div>
</fieldset>
<% end %>
This produces a form that looks correct (well, mostly anyways), but the radio buttons are all part of one set. When selecting an answer on one question, it deselects the answer from all other questions, since they’re part of the same set. Here’s the pertinent HTML generated:
<input class="radio_buttons optional" id="grade_answer_31" name="grade[answer]" type="radio" value="31"/>
The problem here of course is with the name= html attribute. It is pointing to grade. I need it to be something like name="grade[:question_id][:answer_id]". If I had that, I could collect the information easily in the controller and make the necessary calculations.
I’m making the view on the grades_controller since a grade is what will ultimately be created, but questions and answers are nested under the exam model which makes me a bit confused about where this form/action should reside. Should I maybe make a take_exam action on the exams_controller and handle creating the grade from there?
Ok, so my problem was two-fold:
1.) on my
radio_buttonsinput, I mistakenly used thefvariable fromform_forinstead ofbuilderfrom thefields_forcall2.) I changed
fields_forlike so:Calling
fields_forlike that make a hash of all the radio_button inputs in the formatgrade[questions][:question_id][:answer_id]like I wanted.