This is part of the params hash this code has created:
Parameters: {"items"=>{"727"=>"", "5131"=>"", "642"=>""}}
It is concatenating item.id and item.quantity into the keys of the
hash instead of one being the key and the other being the value. I
want to produce a hash called "items" that has a key value pairs that
look like this.
Parameters: {"items"=>{"72"=>"7", "51"=>"31", "64"=>"2"}}
In my :update_cart action I need to access this hash so I can get the
quantity of each item by referencing it's id in the hash.
As I have read hashes don't guarantee that the key value pairs will be
the same every time. Is this correct?
This is blowing up what I'm trying to do. The keys in my params hash
that my form is sending out has a different value each time. It's like
the values are playing musical chairs with their associates keys.
Here's the part of my params hash I'm speaking of:
The nested keys are the ids of objects in a shopping cart and the
values are each one's quantity.
{"items"=>{"72"=>"1", "51"=>"0", "62"=>"0", "64"=>"1"}
Yep, that should work, or you want to say that if you enter some value
into the textbox (eg 10) for the item 71 you've got something
different from 5 on the server?
Each time I submit the form each key will have a different value.
NOTE: I am not entering new content into the text fields, simply
resubmitting what's already there. The values just get randomly
reassigned to different keys each time. The order of the Keys never
change though.
Here's what my log is showing me after clicking submit three times:
It's even worse with more items in the cart.
Parameters: {"items"=>{"72"=>"3", "51"=>"2", "64"=>"1"}}
Parameters: {"items"=>{"72"=>"3", "51"=>"1", "64"=>"2"}}
Parameters: {"items"=>{"72"=>"3", "51"=>"2", "64"=>"1"}}
Are you sure your /page/ is being consistently generated? Have you
used 'view source' to confirm the values in the form are as you think
they should be, each time?
If so, perhaps post the relevant part of the form markup.
this table tag should be inside the form tag, but that's unlikely to
cause this problem. And of course you should quote all attribute
values, and validate your markup to be on the safe side.
Other than that, I don't see any reason for this to be unreliable on
submission, unless there's some JavaScript tweaking it on the fly.
But I'm still wondering if it's getting generated identically each time.
Oh, and what client/browser are you using when you see these
errors? Are you sure you're not throwing JS errors? Hopefully
you're using Firefox with Firebug installed...
And after you submit it you will get {"items"=>{"72"=>"3", "51"=>"2",
"64"=>"1"}}. It's just impossible to get anything else there
If you are getting something else look at the HTML again, and check
what values were there. Considering the code you've posted either
item.quantity is a non-deterministic method, either there is some
stupid bug somewhere.
Inside the update_cart action I have a loop that is running through
params[:items] and assigning the values to multiple @cart.item
properies. Apparently my looping construct is reorganizing the info in
a way other than the params[:items] specified. Once the loop is ran it
re-renders the update_cart.html.erb view that sent params[:items] out
in the first place with the newly modified @cart.item values.
Woops. I should have picked up on that before.
Maybe you guys have some thoughts on how to fix my "sloppy" loop
construct below?
def update_cart
i = 0
@cart = find_cart # A Session based Cart instance
params[:items].each do |k, v|
@cart.items[i].quantity = "#{v}".to_i
i += 1
end
end
without seeing the rest of the cart code, this is just a guess, but
shouldn't
@cart.items[i].quantity = "#{v}".to_i
be
@cart.items[k].quantity = "#{v}".to_i
This ended up being the working loop construct that solved the issue.
def update_cart
@cart = find_cart
# Loop thru the existing cart_item instances and assign the new
incoming
# quantity to each one based on the params hash.
@cart.items.each do |item|
item_quantity = params[:items]["#{item.id}"].to_i
if item_quantity == 0
@cart.items.delete(item)
else
item.quantity = item_quantity
end
end
redirect_to :action => "index_cart"
end