从new动作创建User嵌套StockShipment记录时遇未授权参数错误
问题原因分析
你遇到的Unpermitted parameter: :stock_shipments错误,核心是表单结构、控制器逻辑和强参数三者不匹配:
- 你试图通过User的嵌套属性创建多个StockShipment,但表单却以
[@user, @stock_shipment]为模型,导致参数结构混乱; - 控制器create方法错误地尝试单独构建StockShipment,而非通过User的嵌套属性批量创建;
- 强参数配置的是StockShipment的嵌套属性,但实际参数结构不符合预期。
分步解决方案
1. 修正表单结构
表单应以User为核心模型,利用fields_for生成多个StockShipment的嵌套字段:
<%= form_with model: @user do |form| %> <!-- 循环生成多个StockShipment字段,默认构建2个可按需调整 --> <%= form.fields_for :stock_shipments do |shipment_form| %> <%= render 'shared/shipment_fields', form: shipment_form, locals: { user: current_user, user_stock: @user_stock } %> <% end %> <!-- 添加提交按钮 --> <%= form.submit "Confirmar envíos" %> <% end %>
2. 调整控制器逻辑
new动作:为用户预构建多个空的StockShipment
def new @user = current_user # 预构建2个StockShipment,可根据需求修改数量 2.times { @user.stock_shipments.build } # 按需获取UserStock,若参数来自路由可调整为params[:user_stock_id] @user_stock = UserStock.find(...) end
create动作:通过User更新批量创建StockShipment
def create @user = current_user @user_stock = UserStock.find(params[:user][:stock_shipments_attributes].values.first[:user_stock_id]) if @user.update(user_params) # 给每个新创建的StockShipment发送通知邮件 @user.stock_shipments.last(params[:user][:stock_shipments_attributes].size).each do |shipment| ShipmentNotificationMailer.new_shipment_notification(shipment).deliver_later end redirect_to user_stock_shipments_path(current_user), status: :see_other else puts @user.errors.full_messages.inspect render :new end end
3. 修正强参数配置
现在需要允许User模型的stock_shipments_attributes,而非StockShipment的嵌套属性:
private def user_params params.require(:user).permit( stock_shipments_attributes: [ :id, :country, :phone, :email, :name, :quantity, :address, :city, :province, :postalcode, :surname, :user_id, :campaign_id, :gift_selection_id, :delivery_date, :stock_variation, :description, :user_stock_id, :_destroy ] ) end
4. 确认关联关系
确保User和StockShipment的关联定义正确:
# app/models/user.rb class User < ApplicationRecord has_many :stock_shipments, dependent: :destroy accepts_nested_attributes_for :stock_shipments, reject_if: :all_blank, allow_destroy: true end # app/models/stock_shipment.rb class StockShipment < ApplicationRecord belongs_to :user end
关键说明
- 表单以User为模型后,提交的参数会变为
user[stock_shipments_attributes][...],与强参数配置匹配; - 通过
@user.update(user_params)触发嵌套属性的批量创建,无需单独调用build和save; - 如果需要支持动态添加/删除StockShipment字段,可结合JavaScript实现,但当前方案先解决批量创建的核心问题。
内容的提问来源于stack exchange,提问作者user3074558
相关产品推荐
相关产品推荐

