2

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?

12
  • You show your Products table as having two columns, then it looks like it should have 3 columns after your save? Can you clarify this? Commented Aug 7, 2015 at 22:39
  • So you are trying to save three (or more) records at a time? Commented Aug 7, 2015 at 22:42
  • Post your web server logs. More than just the one line, particularly the part that shows what params are being passed in by the form. If you are trying to save multiple records into the DB you will have to loop through them in the controller and save each one. Commented Aug 7, 2015 at 22:46
  • Also what does your controller params whitelist look like? The require(...).permit(.... part. Commented Aug 7, 2015 at 22:47
  • I see you tagged this as Rails 3.2. In Rails 4 they use a whitelist of parameters rather than attr_accessor. Commented Aug 7, 2015 at 23:02

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

What error are you getting with .create? Any different? I added a loop method alternative.
I edited all my post and I added my last tried according with your answer is saving...but not correctly.
Is not exactly the answer that i wanted but helped me to create. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.