我有一个简单的竞赛结构:
我正在尝试从用户视图中的表单向控制器获取用户对每个问题的答案。长话短说,我无法使用 <%= collection_radio_buttons ... %>
,因为该方法不合适。我的模型中没有针对每个问题的每个答案的一列。 answer_option不是我的问题表中的列,它是一个关联,因为它是另一个表...(或者您知道如何对此进行帮助吗?)
因此,我通过在每个问题的Answers_options上创建循环并使用html输入和标签来绕过此问题,如下所示:
<%= 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 %>
但是现在的问题是在控制器中获取这些值。似乎用this question我必须用params[:something]
来获得它,并且:something
是输入的名称。那正确吗?现在我知道,将params[:name]
(对于一个问题的所有相关单选按钮都相同)直接获取已检查的单选,还是要做另一件事?
这是我现在拥有的东西,因为我其余代码的结构比竞赛的要大,所以有些东西可以忽略。这是在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
因此,有一种获取此值的方法,还是应该更改我的数据库结构,以便每个问题的每个答案都有一列?还是另一种解决方案?谢谢!
编辑:
我也尝试替换此:
<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>
使用此:
<%= 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 %>
并且用user_choice = params[:answer_option]
获取控制器中的值,但是当我用check_box
替换radio_button
时,它弄乱了名称,ID等值,我无法选择了。
编辑2:
通过添加此结构:
<%= q.radio_button :answer_option, answer_option.answer %>
<%= q.label :answer_option, answer_option.answer %>
它可以正常工作(没有错误),但是名称是自动设置的,并且不是每个问题都特定的名称,例如contest[questions][answer_option]
,并且标签的for设置为contest_questions_answer_option
,因此单击标签不会链接到复选框。
已设法使用此结构的单选按钮检索复选框的值:
<%= q.radio_button answer_option.question_id, answer_option.answer %>
<%= q.label "#{answer_option.question_id}_#{answer_option.answer.parameterize.underscore}", answer_option.answer %>
和控制器:
user_choices = params[:contest][:questions]
user_contest.questions.each do |question|
question[:user_answer] = "#{user_choices[:'#{question.id}']}"
question.save
end