I have a simple structure of contest:
For this I feel like what I've created is a good structure:
I am trying to get the answers of a user for each question from the form in my view to my controller. Long story short, I was unable to use the <%= collection_radio_buttons ... %>
because the method wouldn't be right. There is not one column in my model for each answer to each question. answer_option is not a column in my questions table it's an association because it's another table... (or would you know how to help on that?)
So I've bypassed this issue by creating loops on answers_options of each question and using html inputs and labels, like this:
<%= simple_form_for @contest, url: contest_send_quizz_path(@contest), method: :post do |f| %>
<%= f.fields_for :questions do |q| %>
<% @questions.each do |question| %>
<h4 class="mt-5"><%= question.title %></h4>
<% question.answer_options.each do |answer_option| %>
<div class="inputGroup">
<input type="radio" name=<%= answer_option.question_id %> value="<%= answer_option.answer %>" id=<%= answer_option.id %> />
<label for=<%= answer_option.id %>><%= answer_option.answer %></label>
</div>
<% end %>
<% end %>
<% end %>
<div class="mt-3">
<span class="button-effect-2">
<%= f.button :button, "Envoyer", type: :submit, class:"text-white" %>
</span>
</div>
<% end %>
However now the problem is fetching those values in the controller. It seems with this question that I'd have to get it with params[:something]
and that :something
being the name of the input. Is that right? And now that I know that, does putting params[:name]
(which is the same for all concerned radio buttons of one question) directly get the checked radio, or is there another thing to do?
Here is what I have for now, there is stuff to ignore since the structure of the rest of my code is bigger than just the contest. This is in the ContestsController
:
def show
@contest = Contest.find(params[:id])
authorize @contest
@time_left = seconds_to_units(@contest.deadline - Time.now)
@is_done = @contest.deadline < Time.now
if @is_done
get_winner
end
@questions = @contest.questions.includes([:answer_options])
end
def send_quizz
@contest = Contest.find(params[:contest_id])
@questions = @contest.questions.includes([:answer_options])
authorize @contest
current_user.contests << @contest
user_choice = # TODO : Get checked radio value from view
user_contest = current_user.contests.select { |contest| contest.title == @contest.title }.first
user_contest.questions.each do |question|
question.user_answer = user_choice
end
# TODO : make sure every questions were answered before submitting request
redirect_to contests_path
flash[:notice] = "Ta réponse a été prise en compte"
end
So is there a way to get this value, or should I change my db structure so that each question has one column for each answer? Or maybe another solution? Thanks !
EDIT:
I also tried replacing this:
<input type="radio" name="<%= answer_option.question_id %>" value="<%= answer_option.answer %>" id="<%= answer_option.id %>" />
<label for="<%= answer_option.id %>"><%= answer_option.answer %></label>
With this:
<%= q.check_box :answer_option, name:answer_option.question_id, id:answer_option.id %>
<%= q.label :answer_option, answer_option.answer, for:answer_option.id %>
And getting the value in the controller with user_choice = params[:answer_option]
but when I replaced check_box
with radio_button
, it messed up the name, id etc. values AND I couldn't select anymore.
EDIT 2:
By adding this structure:
<%= q.radio_button :answer_option, answer_option.answer %>
<%= q.label :answer_option, answer_option.answer %>
It works (no errors), however the name is set automatically and to something not specific to each question i.e. contest[questions][answer_option]
and the label's for is set to contest_questions_answer_option
, therefore clicking on the label does not link to the checkbox.
Managed to retrieve the value of the checkbox with this structure for the radio-buttons:
<%= q.radio_button answer_option.question_id, answer_option.answer %>
<%= q.label "#{answer_option.question_id}_#{answer_option.answer.parameterize.underscore}", answer_option.answer %>
And the controller:
user_choices = params[:contest][:questions]
user_contest.questions.each do |question|
question[:user_answer] = "#{user_choices[:'#{question.id}']}"
question.save
end