Carlos Morales
Carlos Morales

Reputation: 1149

How can save array params using the controller?

My controller is not saving correctly array params.

Database

|categories|
 |id| |name|
   1    HW
   2    SF
   3    PC

|products|
 |id| |amount| |category_id|

But after saving the table 'PRODUCTS', should save array params will be like this demo

|products|
 |id| |amount| |category_id|
   1     100          1
   2     200          2
   3     300          3

Controller:

def new
  @categories = Category.all
  @obj_product = Product.new(params[:obj_product])
end

def create
  params[:obj_product].each do |key , value| 
    o = FlowBudgetDetail.new( :amount => value , :category_id => key)
    o.save
  end

  if o.save()
    redirect_to :action=>"index"
  else
    redirect_to :action=>"new"
  end
end

View:

<% form_for :obj_product, :url => {:action=>'create'} do |f| %>
   <% @categories.each do |category| %>
     <%= f.text_field :category_id , :name => "obj_product[array_#{category.id}][category_id]"%>
     <%= f.text_field :amount      , :name => "obj_product[array_#{category.id}][amount]" %>
   <% end %>
<$ end %>

Log is showing all parameters but is just creating one insert:

Processing ProductController#create (for 127.0.0.1 at 2015-08-07 17:23:26) [POST]
Parameters: {"commit"=>"Save", "obj_product"=> {"array_1"=>{"amount"=>"100","category_id"=>"1"},"array_2"=>{"amount"=>"300","category_id"=>"2"},"array_3"=>{"amount"=>"300","category_id"=>"3"} }}
INSERT INTO `products` (`category_id`, `amount`) VALUES( 0, 1)
INSERT INTO `products` (`category_id`, `amount`) VALUES( 0, 1)
INSERT INTO `products` (`category_id`, `amount`) VALUES( 0, 1)

This should save this:

INSERT INTO `products` (`category_id`, `amount`) VALUES( 1, 100)
INSERT INTO `products` (`category_id`, `amount`) VALUES( 2, 200)
INSERT INTO `products` (`category_id`, `amount`) VALUES( 3, 300)

Is saving incorrect information (incorrect params)

Please somebody can help me?

Upvotes: 2

Views: 2614

Answers (1)

Beartech
Beartech

Reputation: 6421

You are trying to create multiple records at once but you are trying to do it using a single call to new this is important!!! In your Controller#new action you only ask the DB for ONE object. That's fine I guess to get the form fields you need since you are using your @categories to do the number of loops needed. But in your Controller#create action you do:

 obj_product.new(params[:obj_product]) 

You could try:

 obj_product.create(params[:obj_product]) 

But this will NOT work because your params are:

"flow_budget_detail"=> {"1"=>{"amount"=>"100"},"2"=>{"amount"=>"300"},,"2"=>{"amount"=>"300"} }

If you want to do this you have to create all of the @obj_products before hand in the Controller#new action. That way if there are 3 categories associated, you are passing three Product objects to the form, which will then return a VERY different params hash. Your params hash would have to look like:

[{"category_id" => "1", "amount"=>"100"},{"category_id" => "2", "amount"=>"200",...}]

But unless you rewrite your controller and form that won't work. You could do:

def create
  if FlowBudgetDetail.transaction do
       params["flow_budget_details"].each do |k,v|
         new_record = FlowBudgetDetail.new("category_id" => k, "amount" => v)
         new_record.save
       end
   end
      redirect_to :action=>"index"
   else
     redirect_to :action=>"new"
   end
end

OK, this should work verbatim. Don't go changing the Key in params["flow_budget_details"].each because that is one reason you are getting the wrong results. Also don't change the order of `.new("category_id" => k, "amount" => v)' because you made it backwards from what I told you last time and that also screwed up your results.

Do exactly this and post the results.

Upvotes: 4

Related Questions