嵌套属性适用于创建但更新记录时失败

我有嵌套属性的问题。 创建工作,但是当我更新时,错误消息显示我没有设置关系中的值。 我找不到原因。

主要模型

class Product  true, :reject_if => proc { | r | r["name"].blank? or r["value"].blank? } end 

嵌套模型

 class ProductOption  true validates :value, :presence => true end 

控制器有点短路。 Items是Product与has_one相关的模型

 class Admin::ProductsController  "alert( 'Daten gespeichert!' );" } else format.js { render :js => 'alert( "Fehler beim Speichern!" );' } end end end def update respond_to do |format| if @product.update( product_params ) format.js { render :js => "alert( 'Daten gespeichert!' );" } else require "pp" pp @product.errors format.js { render :js => 'alert( "Fehler beim Speichern!" );' } end end end private # UPDATE: creating the product_options at this time # produces the described error :) def set_product @item = Item.find_by_id( params[ :item_id ] ) if params[ :item_id ] @product = @item.product ? @item.product : @item.build_product # WRONG Place for generating new options # 2.times { @product.product_options.build } end def product_params params.require( :product ).permit( :item_id, :name, :title, :active, :product_options_attributes => [ :id, :name, :value, :_destroy ] ) end end 

创建的控制台输出正常工作,看起来像

 Started POST "/admin/items/653/product" for 127.0.0.1 at 2014-02-14 15:12:14 +0100 Processing by Admin::ProductsController#create as JS Parameters: {"utf8"=>"✓", "product"=>{"item_id"=>"653", "name"=>"1", "title"=>"1", "active"=>"1", "product_options_attributes"=>{"0"=>{"name"=>"aaa", "value"=>"aaaa"}}}, "commit"=>"Create Product", "item_id"=>"653"} User Load (1.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1 (0.6ms) BEGIN SQL (17.5ms) INSERT INTO "products" ("created_at", "item_id", "name", "title", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00], ["item_id", 653], ["name", "1"], ["title", "1"], ["updated_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00]] SQL (1.3ms) INSERT INTO "product_options" ("created_at", "name", "product_id", "updated_at", "value") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00], ["name", "aaa"], ["product_id", 28], ["updated_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00], ["value", "aaaa"]] Item Load (1.0ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 ORDER BY "items"."id" ASC LIMIT 1 [["id", 653]] ProductOption Load (1.3ms) SELECT "product_options".* FROM "product_options" WHERE "product_options"."product_id" = $1 [["product_id", 28]] Rendered admin/products/_show.html.erb (7.6ms) Rendered admin/products/create.js.erb (9.2ms) Completed 200 OK in 448ms (Views: 40.0ms | ActiveRecord: 27.1ms) 

更新。 我不工作,并给出嵌套字段为空的错误。 它是更新方法中的pp

 Started PATCH "/admin/items/653/product" for 127.0.0.1 at 2014-02-14 15:15:03 +0100 Processing by Admin::ProductsController#update as JS Parameters: {"utf8"=>"✓", "product"=>{"item_id"=>"653", "name"=>"1", "title"=>"1", "active"=>"1", "product_options_attributes"=>{"0"=>{"name"=>"aaa", "value"=>"aaaa", "id"=>"9"}, "1"=>{"name"=>"bbb", "value"=>"bbbb"}}}, "commit"=>"Update Product", "item_id"=>"653"} User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1 Item Load (0.6ms) SELECT "items".* FROM "items" WHERE "items"."id" = 653 LIMIT 1 Product Load (0.9ms) SELECT "products".* FROM "products" WHERE "products"."item_id" = $1 ORDER BY "products"."id" ASC LIMIT 1 [["item_id", 653]] (0.6ms) BEGIN ProductOption Load (1.3ms) SELECT "product_options".* FROM "product_options" WHERE "product_options"."product_id" = $1 AND "product_options"."id" IN (9) [["product_id", 28]] (0.5ms) ROLLBACK #<ActiveModel::Errors:0x007f8bdeb9f818 @base= #, @messages= {:"product_options.name"=>["can't be blank"], :"product_options.value"=>["can't be blank"]}> Completed 200 OK in 18ms (Views: 0.1ms | ActiveRecord: 5.1ms) 

我想我知道你的代码有什么问题。 accepts_nested_attributes_for不要求您构建任何关联的模型。 如果传入适当的参数,则模型会自动构建或更新关联。

在您update方法的情况下,您执行的操作如下:

  • 您找到相关产品。 到目前为止一切顺利(尽管您实际上可以在表单中使用特定的产品ID)
  • 然后构建两个产品选项(在#set_product )。 这就是问题。
  • 最后,您将根据参数更新模型。

现在第二步的问题是你基本上构建了两个空的关联实例。 那些不受accepts_nested_attributes影响。 因此,您正在尝试保存2 + 2个产品选项(您构建的产品和由参数创建的产品)。 显然,由于两个模型没有设置属性,因此您会收到validation错误。

您可以通过从ProductOption中删除validation器来确保我的假设是正确的。 在更新时,您应该保留4个关联的产品选项。