2

I am submitting data via ajax to be inserted into the database.

Due to the complex nature of the view and the forms I am sending some redundant information (two forms combined in one).

e.g. the data I'm sending is

partner_id:940
partner_ref: 1
product_1_id:50
product_1_quantity:1

in my controller I then submit everything bar the partner_id and partner_ref, to do this I am counting the size of the POST array, subtracting 2 to account for the 2 parameters I don't want to store and then dividing that by two to get the actual number of products being stored so the result should be 1 but 2 entries are being stored in the table.

# get number of parameters passed and subtract 2 for partner_id and partner_ref
# divide count by two to get actual number of line items
line_items = ((params.size - 2) / 2)

count = 1
for i in count..line_items  
  item_id  = params["product_#{count}_id"]
  quantity = params["product_#{count}_quantity"]

  # had to add this conditional statement to prevent NULL entries in the database
  if !item_id.nil? and !quantity.nil?
    line_item = QuoteItem.create(:price_list_item_id => item_id, :quantity => quantity)
  end
    count = count + 1
end

render :text => line_items # => 2 when it should be 1

It must be something stupid but can't see anything wrong.

martincarlin87
  • 10,848
  • 24
  • 98
  • 145

2 Answers2

2

The parameters that rails logs by default aren't the entire params hash. For example, in my application if I do a search I see the following parameters logged by default in rails:

Parameters: {"utf8"=>"✓", "term"=>"searchterm"}

But if I log the result of calling inspect on the params hash I get:

{"utf8"=>"✓", "term"=>"searchterm", "action"=>"search", "controller"=>"home"}

This is because rails uses the params hash to store the controller and action name in the params hash. As you've commented, on certain (POST) forms you'll also get CSRF parameters added too.

You would be better off looking at how rails can interpret parameters as arrays and hashes. As MrYoshiji commented if you use products[][id] rails will translate it into an array of hashes. You can also use explicit array references for position.

So with text field tags (with values specified to illustrate more clearly):

text_field_tag("products[][id]", "1")
text_field_tag("products[][quantity]", "11")
text_field_tag("products[][id]", "2")
text_field_tag("products[][quantity]", "22")

Your params will contain a products value like this:

"products"=>[{"id"=>"1", "quantity"=>"11"}, {"id"=>"2", "quantity"=>"22"}]

Which means you don't have to calculate anything, you can just iterate over products and process them:

params["products"].each do |product_hash|
  product_hash["id"]       # The id
  product_hash["quantity"] # The quantity
end
Shadwell
  • 34,314
  • 14
  • 94
  • 99
0

You should inspect your incoming params. You are just accounting for two partner params, but in actual scenario there are could be more params coming like controller, action or authentication token etc.

techvineet
  • 5,041
  • 2
  • 30
  • 28