如何用SimpleForm的simple_fields_for创建新对象而非更新现有对象?
解决方案:让嵌套表单创建新的ProductCategory对象
要解决这个问题,核心是让simple_fields_for针对未保存的新对象生成表单,而不是关联的现有对象——这就是之前自动出现带有现有id的隐藏字段的原因(SimpleForm默认会认为你要更新已存在的关联对象)。
步骤1:在控制器中构建新的关联对象
在你的ProductsController的new动作里,为新创建的Product构建一个空的ProductCategory对象:
def new @product = Product.new # 构建一个未保存的新ProductCategory,关联到当前Product @product.build_product_category end
步骤2:保持(或调整)视图中的表单代码
你的视图代码可以保持原样,因为现在@product.product_category指向的是一个新的空对象,SimpleForm会自动为它生成创建用的表单字段,不会添加带有现有id的隐藏输入:
<%= f.simple_fields_for :product_category do |g| %> <%= g.input :name, placeholder: "Category name", label: "Category", disabled: true, input_html: {id: "new_product_category_input", style: "width: 300px"} %> <% end %>
如果想更明确地指定使用新对象,也可以写成:
<%= f.simple_fields_for :product_category, @product.product_category do |g| %> <%= g.input :name, placeholder: "Category name", label: "Category", disabled: true, input_html: {id: "new_product_category_input", style: "width: 300px"} %> <% end %>
关键说明
- 为什么这样有效?当你调用
build_product_category时,会创建一个未保存到数据库的ProductCategory实例(没有id值),SimpleForm识别到这是新对象,就不会生成用于更新的隐藏id字段。 - 确保你的模型配置了
accepts_nested_attributes_for,否则嵌套表单的参数无法被正确处理。比如在Product模型中:class Product < ApplicationRecord # 根据你的关联关系调整:has_one 或 belongs_to has_one :product_category, dependent: :destroy accepts_nested_attributes_for :product_category, allow_destroy: true end
这样修改后,提交表单时就会创建新的ProductCategory对象,并关联到新创建的Product上,而不是更新现有对象。
内容的提问来源于stack exchange,提问作者Augusto Carmo
相关产品推荐
相关产品推荐

