Search code examples
ruby-on-railsrubynested-attributesruby-on-rails-2

Issue saving in nested form


I followed thos steps http://railscasts.com/episodes/197-nested-model-form-part-2 and changed purchase_product "survey" and supplier_product as "question" but is not saving and also not saving nested attributes.

Here is the controller /app/controller/purchase_product_controller.rb

class PurchaseProductController < ApplicationController
 def new
   @purchase = PurchaseProduct.new
   1.times do
    supplier_product = @purchase.supplier_products.build
   end
 end

 def create
   @purchase = PurchaseProduct.new(params[:purchase])
   if @purchase.save
     flash[:notice] = "Successfully created purchase."
     redirect_to :action=>"index"
   else
     render :action => 'new'
   end
 end
end

Here models:

class PurchaseProduct < ActiveRecord::Base
   has_many :supplier_products
   accepts_nested_attributes_for :supplier_products ,:allow_destroy => true
end

class SupplierProduct < ActiveRecord::Base
   belongs_to :purchase_product
end

Here is my routes: /config/routes.rb

ActionController::Routing::Routes.draw do |map|
  map.root :controller => "purchase_product", :action=>"index"
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

Here is the view: /app/view/purchase_product/new.html.erb

<% form_for @purchase, :url => {:controller=>"purchase_product",:action=>'create'}, :html => {:id => 'new_product_form'} do |f|  %>
   Name: <%= f.text_field :name   %>
   <% f.fields_for :supplier_products do |builder| %>
     <%= render "supplier_product_fields", :f => builder %>
   <% end %>
   <p><%= link_to_add_fields "Add Supplier Product", f, :supplier_products %></p>
   <p><%= f.submit "Submit" %></p>
<% end %>

Here is the partial view: /app/view/purchase_product/_supplier_product_fields.html.erb

<div class="fields">
   Type Money: <%= f.select(:type_money,([["%", 0], ["$", 1] ]) ) %>   
   Cost: <%= f.text_field :amount  %><%= link_to_remove_fields "remove", f %> 
</div>

But was not saving and got this log:

Processing PurchaseProductController#create (for 127.0.0.1 at 2014-08-06 13:48:31) [POST]
  Parameters: {"purchase_product"=>{"name"=>"testing", "supplier_products_attributes"=>{"0"=>{"amount"=>"333", "type_money"=>"0", "_destroy"=>""}}}, "commit"=>"Submit"}
  PurchaseProduct Columns (0.6ms)   SHOW FIELDS FROM `purchase_products`
  SQL (0.1ms)   BEGIN
  PurchaseProduct Create (0.0ms)   Mysql::Error: Column 'name' cannot be null: INSERT INTO `purchase_products` (`name`, `created_at`, `updated_at`) VALUES(NULL, '2014-08-06 18:48:31', '2014-08-06 18:48:31')
  SQL (0.1ms)   ROLLBACK
ActiveRecord::StatementInvalid (Mysql::Error: Column 'name' cannot be null: INSERT INTO `purchase_products` (`name`, `created_at`, `updated_at`) VALUES(NULL, '2014-08-06 18:48:31', '2014-08-06 18:48:31')):

I solved the problem of saving, changing this param in the view and saved but is not saving the other attributes

Name: <%= text_field_tag "name",@name,:name=>"purchase_product[name]"   %>

I got this LOG:

Processing PurchaseProductController#create (for 127.0.0.1 at 2014-08-06 14:00:04) [POST]
 Parameters: {"purchase_product"=>{"name"=>"TESTING", "supplier_products_attributes"=>{"0"=>{"amount"=>"100", "type_money"=>"0", "_destroy"=>""}}}, "commit"=>"Submit"}
  PurchaseProduct Columns (0.7ms)   SHOW FIELDS FROM `purchase_products`
  SQL (0.1ms)   BEGIN
 PurchaseProduct Create (0.3ms)   INSERT INTO `purchase_products` (`name`, `created_at`, `updated_at`) VALUES('TESTING', '2014-08-06 19:00:04', '2014-08-06 19:00:04')
 SQL (37.0ms)   COMMIT
Redirected to http://localhost:3000/
Completed in 44ms (DB: 38) | 302 Found [http://localhost/purchase_product/create]

I spent a long time searching about a solution also I recreated the project several times.

Attributes from supplier products are not saving.

Please somebody can help me with this issue?


Solution

  • In your controller you are grabbing the purchase key from the params hash.

    @purchase = PurchaseProduct.new(params[:purchase])
    

    But the parameters you need are actually going to be in params[:purchase_product].

    @purchase = PurchaseProduct.new(params[:purchase_product])
    

    When you use the form_for helper, the key will be named after the model which the form is built around. In your case it is a PurchaseProduct, hence why they'll be in params[:purchase_product]