Rails自定义name属性的表单无法向控制器传递正确参数
Rails调查问卷批量提交答案的问题解决
问题根源
你当前的问题有两个核心:
- 表单手动设置了
name: "answer_value_#{index}",导致提交的参数没有嵌套在:answer命名空间下,触发ParameterMissing错误; - 现有代码只处理单个
Answer实例的创建,无法批量生成多个问题对应的答案记录。
解决方案
1. 修改表单代码
调整表单的参数结构,让每个问题的答案都包含question_id和answer_choice,并嵌套在answers数组中,这样提交后能批量获取所有问题的回答:
<%= form_with url: submit_survey_path(@survey), method: :post do |form| %> <% @questions.each do |question| %> <div class="question-group"> <p><%= question.title %></p> <%# 为每个问题生成单选按钮,参数关联question_id %> <%= form.radio_button "answers[][answer_choice]", "1", id: "q_#{question.id}_yes" %> <%= form.label "q_#{question.id}_yes", "是" %> <%= form.radio_button "answers[][answer_choice]", "0", id: "q_#{question.id}_no" %> <%= form.label "q_#{question.id}_no", "否" %> <%# 隐藏字段传递question_id,确保答案能关联到对应问题 %> <%= form.hidden_field "answers[][question_id]", value: question.id %> </div> <% end %> <%= form.submit "提交问卷" %> <% end %>
2. 调整控制器代码
修改create方法,遍历提交的答案数组,批量创建Answer记录,同时修正强参数规则:
class SurveyResultsController < ApplicationController def show @survey = Survey.find(params[:id]) @questions = @survey.questions # 不需要初始化@answers,因为是批量创建 end def create @survey = Survey.find(params[:survey_id]) # 遍历答案参数,逐个创建记录 params[:answers].each do |answer_attrs| Answer.create( question_id: answer_attrs[:question_id], answer_choice: answer_attrs[:answer_choice], survey_id: @survey.id # 如果Answer模型关联了Survey,加上这个字段 ) end redirect_to root_url, notice: "问卷提交成功" end private def answer_params # 允许批量提交answers数组,包含question_id和answer_choice字段 params.permit(answers: [:question_id, :answer_choice]) end end
3. 修正路由配置
确保路由能正确匹配问卷提交的请求,把create动作关联到具体的Survey:
# config/routes.rb Rails.application.routes.draw do resources :surveys do member do get :show_survey # 对应SurveyResultsController的show方法,显示问卷 post :submit_survey # 对应create方法,提交问卷 end end end
关键说明
- 表单不再手动自定义
name,而是通过answers[][xxx]的格式让参数自动组织成数组,方便批量处理; - 控制器不再尝试创建单个
Answer实例,而是遍历参数数组批量生成记录; - 隐藏字段
question_id确保每个答案能关联到对应的问题,避免数据错乱。
内容的提问来源于stack exchange,提问作者auto
相关产品推荐
相关产品推荐

