Rails嵌套属性哈希键触发QuoteLineItem unknown attribute '0'报错
Rails 嵌套表单提交报
unknown attribute '0' for QuoteLineItem 问题定位 核心原因
报错本质是参数结构和模型嵌套属性约定不匹配:新增二级嵌套组件逻辑后,传给line_item.assign_attributes(opts)的opts哈希,把数字索引(0、1、2…)当成了QuoteLineItem的属性key,Rails找不到对应字段就抛出异常,和add_or_update_item_quantity本身的数量计算逻辑无关。
逐点排查修复
检查模型嵌套属性配置
三级关联必须逐层声明accepts_nested_attributes_for,漏配任何一层都会导致参数解析异常:# app/models/quote.rb class Quote < ApplicationRecord has_many :quote_line_items, dependent: :destroy # 声明允许嵌套处理报价条目 accepts_nested_attributes_for :quote_line_items, allow_destroy: true, reject_if: :all_blank end # app/models/quote_line_item.rb class QuoteLineItem < ApplicationRecord belongs_to :quote has_many :quote_line_item_components, dependent: :destroy has_many :child_components, through: :quote_line_item_components, source: :child_quote_line_item # 声明允许嵌套处理条目组件 accepts_nested_attributes_for :quote_line_item_components, allow_destroy: true, reject_if: :all_blank end # app/models/quote_line_item_component.rb class QuoteLineItemComponent < ApplicationRecord belongs_to :parent_quote_line_item, class_name: "QuoteLineItem" belongs_to :child_quote_line_item, class_name: "QuoteLineItem" end修正Strong Parameters白名单
嵌套属性必须用*_attributes作为key声明,写错后缀或者漏写层级会把参数结构打平,直接把数字索引暴露到模型属性层:# 错误写法(会触发本次报错) def quote_params params.require(:quote).permit(:user_id, :status, quote_line_items: [:id, :equipment_id, :quantity, quote_line_item_components: []]) end # 正确写法 def quote_params params.require(:quote).permit( :user_id, :status, quote_line_items_attributes: [ :id, :equipment_id, :quantity, :_destroy, quote_line_item_components_attributes: [ :id, :child_quote_line_item_id, :component_quantity, :_destroy ] ] ) end注意:Formtastic会自动生成符合
*_attributes约定的嵌套参数,如果提交参数里没有这个后缀,说明表单的嵌套块层级写错了。校验Formtastic表单结构
嵌套表单必须逐层包裹semantic_fields_for,跨层级写块会生成错误结构的参数:<%# 正确嵌套结构 %> <%= semantic_form_for @quote do |f| %> <%= f.input :status %> <%= f.semantic_fields_for :quote_line_items do |line_item_f| %> <%= line_item_f.input :equipment_id %> <%= line_item_f.input :quantity %> <%# 组件表单块必须放在报价条目的表单块内部 %> <%= line_item_f.semantic_fields_for :quote_line_item_components do |component_f| %> <%= component_f.input :child_quote_line_item_id %> <%= component_f.input :component_quantity %> <% end %> <% end %> <%= f.action :submit %> <% end %>检查参数提取逻辑
正常带嵌套组件的提交参数结构必须符合如下格式:
可以在{ "quote" => { "status" => "open", "quote_line_items_attributes" => { "0" => { "equipment_id" => "12", "quantity" => "2", "quote_line_item_components_attributes" => { "0" => { "child_quote_line_item_id" => "34", "component_quantity" => "1" } } } } } }assign_attributes前加puts opts.inspect打日志,如果打印的哈希顶层key是0、1这类数字,说明在add_or_update_item_quantity方法里取参数时搞错了层级——把quote_line_items_attributes下以数字为key的子哈希,直接当成了单条QuoteLineItem的属性哈希传给了赋值方法,这是这类报错最常见的触发场景。
内容的提问来源于stack exchange,提问作者Johanna Ruiz
相关产品推荐
相关产品推荐

