ROR中多组同名单选按钮分组识别与survey_answer_id存储问题
解决ROR问卷单选按钮组区分与答案保存问题
嘿,我来帮你搞定这个问卷单选按钮的问题!我看你现在的核心困扰是多个单选组会被当成同一组,而且没法正确把每个问题对应的选中答案存到SurveyResponse里。咱们一步步来调整代码,解决这两个问题:
1. 先把单选按钮组的命名改对
你现在用survey_answer_id_#{question.id}当单选按钮的name,虽然能区分组,但提交后的参数结构会很乱,控制器处理起来麻烦。咱们换成数组格式的命名,既能保证每个组唯一,又能让参数结构清晰,方便后续保存。
同时,你原来的f.hidden_field :survey_question_id在遍历多个问题时会被覆盖,最后只会提交最后一个问题的ID,这也是个大坑,得一起改。
调整后的表单代码如下:
<% @survey_questions.each do |question| %> <p><%= question.question_content %></p> <% if question.answer_type == "Text Field" %> <div class="field"> <%= label_tag "survey_responses[#{question.id}][answer]", "你的回答" %> <%= text_area_tag "survey_responses[#{question.id}][answer]", nil, id: "survey_response_answer_#{question.id}" %> <%= hidden_field_tag "survey_responses[#{question.id}][survey_question_id]", question.id %> </div><br /> <% else %> <%# 用question ID作为数组键,确保每个单选组唯一 %> <% question.survey_answers.each do |answer| %> <%= radio_button_tag "survey_responses[#{question.id}][survey_answer_id]", answer.id, false, id: "survey_response_answer_#{question.id}_#{answer.id}" %> <%= label_tag "survey_response_answer_#{question.id}_#{answer.id}", answer.answer_content %><br /> <% end %> <%= hidden_field_tag "survey_responses[#{question.id}][survey_question_id]", question.id %> <% end %> <% end %>
2. 控制器里处理提交的参数
现在提交后的参数会是一个以question ID为键的散列,每个键对应的值包含了问题ID和对应的答案(单选的answer ID或文本框内容)。你只需要在SurveyResponsesController的create方法里遍历这个散列,创建对应的SurveyResponse记录就行:
def create # 假设你已经在控制器里拿到了当前问卷@survey params[:survey_responses].each do |_question_id, response_params| response_params[:survey_id] = @survey.id SurveyResponse.create(response_params) end redirect_to survey_path(@survey), notice: '问卷提交成功啦!' end
3. 关键细节说明
- 单选组区分:通过
survey_responses[#{question.id}][survey_answer_id]的命名,每个问题的单选按钮组都有独一无二的name属性,再也不会被当成同一组了。 - 参数不丢失:用
hidden_field_tag指定了每个问题ID对应的参数名,避免了原来hidden字段被覆盖的问题,每个问题的ID都能正确传递到控制器。 - 保存逻辑清晰:遍历参数创建每个问题对应的
SurveyResponse记录,完美符合你“仅存储question id和answer id”的需求。
如果你的需求是用一条SurveyResponse记录保存整个问卷的所有答案(而不是每个问题一条),那你可以调整模型,加一个answers字段存JSON格式的问题-答案映射,但从你的描述来看,上面的方案应该更贴合你的需求。
内容的提问来源于stack exchange,提问作者Joe Doe
相关产品推荐
相关产品推荐

