I have a problem with nested attributes. Creating works but when I update, the error message shows me that the values in the relation are not set. I can't find the reason.
The main model
class Product < ActiveRecord::Base
has_many :product_options
accepts_nested_attributes_for :product_options,
:allow_destroy => true,
:reject_if => proc { | r | r["name"].blank? or r["value"].blank? }
end
The nested model
class ProductOption < ActiveRecord::Base
belongs_to :product
validates :name, :presence => true
validates :value, :presence => true
end
The controller is a bit shorted. Items is a model where Product is related to as has_one
class Admin::ProductsController < Admin::ApplicationController
before_action :set_product, only: [ :new, :show, :edit, :update, :destroy ]
def create
@product = Product.new( product_params )
respond_to do |format|
if @product.save
@product.product_options.build
format.js { render :js => "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
The console output for the create is working and looks like
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)
The the update. I doesn't work and gives an error that the nested fields are empty. It's the pp inside the update method
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=
#<Product id: 28, item_id: 653, content: nil, active: 1, created_at: "2014-02-14 14:12:14", updated_at: "2014-02-14 14:12:14", name: "1", title: "1", ordernumber: "">,
@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)