Ruby on Rails - Editing multiple rows of data on one form
I think I may have poorly chosen my first application to learn Rails or maybe not...I am trying to set up some simple profit-loss reports for our store Natures Paws.
Working with a legacy schema with Rails has been challenging but, I still have found Rails pleasing to use. Tonight, I ran into a situation where, I wanted to be able to update multiple line items in an order and update the model with this data. Rails was able to handle this so easily once I figured out what to do. (Thanks to the params hash dump shown on a Ruby exception page, I was able to figure out what I was doing wrong).
So, if a view has some code, iterating through some line items (each a row in a database table), like so
<% for @line in @profit_report.report_lines %>
<%= h @line.product_name %>
<%= text_field("line[]", 'wholesale_price', :size => 4, :maxsize => 4, :onchange => 'updateWholeSaleTotal(this.value);') %>
<%= text_field("line[]", 'ourshipping_price', :size => 4, :maxsize => 4) %>
<%= h @line.customer_price %>
<%= h @line.customer_shipping_price %>
<%= text_field("line[]", 'usps_price', :size => 4, :maxsize => 4) %>
<%= h @line.commission_paid %>
<% end %>
Then the Controller code can then update each lines in the model like so...
@params[:line].each do |idx, line|
report_line = ReportLine.find(idx)
report_line.update_attributes(line)
end
I have to say that is pretty sweet.
13 Comments:
Hi there.
I have to thank you a lot. I have been trying to get the same kind of functionality done and couldn't figure it out. I am fairly new to both rails and ruby and could not figure out how to get the text_field to show the right info. When I saw "for @item in @itemlist" I was like duuuuuuhhhhhhh
the part that you also helped me was the text_field "item[]" part. I new how to create the output html but not how to have the rails helper do it. :(
So. I have to thank you twice.
Thanks for the info.
I've been trying a similar thing for 3 days now and I'm still stuck.
I have text_field "item[]", 'quantity' as code in my rhtml. And this is for @item in @items where @items is an array.
Now for display this works correctly. All line items are displayed correctly with their respective quantities.
But I dont know why all quantity text boxes on that page get the name item[quantity] and only the 1st one gets passed to the next function. I would expect the text boxes to be named item[0][quantity], item[1][quantity] and so on...
What am i doing wrong??? I wanted to paste the code here but it doesnt allow me to.
Thank you for describing your approach to multiple-record editing in Rails. I tried applying this technique -- the "line[]", in particular, to a select box and struggled a bit. I was using the select helper method provided in ActionView.
I am editing multiple instances of a "project" domain model.
Here's what ended up working:
<select id="project_<%= project.id %>_organization_id"
name="project[<%= project.id %>][organization_id]">
<%= options_for_select @organizations, project.organization_id %>
</select>
Thanks for the note on the brackets! That's just what I was looking for. It's a bizarre Rails feature, but adding the brackets works.
-Yaron K.
It's important to note that using item[] will only work if you use @item in the for statement. It will not work if you juse use item.
Works
for @item in @items
Doesn't Work
for item in @items
quite useful code!
I found your approach working when editing, not when creating active record objects. Possibly it needs ID to be assigned and my apps leave that to the database. And rails is evolving since the blog entry was created. Anyway, here is my approach for newly created AR objects using a partial, supposing you want to render a collection @lineitems:
Initialize a counter to 0 or 1 in the controller or in the view:
@lineitems_counter = 1
create the partial template, increment the counter after form elements:
<%= text_field(:lineitem, :price, 'index' =%> @lineitems_counter ) %>
%lt;% @lineitems_counter += 1 %>
In the "main" form, no need for iteration code, just render the partial for the entire collection:
<%= render(:partial => "insname" , :collection => @insnames ) %>
sorry, the %lt;% is meant to be <% - it was a while since i entered html entities on the fly :D
this is just great. worked like a charm!
Hi, this has gotten me close, but I'm having trouble getting the format exactly right. I'm still a rails novice, and feel a bit in over my head...
The a have table ten rows which is named toppost and has two columns: id and link_id. I would like to be able to edit the link_id from a drop-down, and then have my database updated to account
Here is the code in my rhtml file:
" <% for i in 1..10 %>
<tr>
<td align=""right""><%= i %></td>
<td align=""left"">
<select name=""toppost[<%= i %>][link_id]"">
<% @links.sort_by{|link| link[:posttime]}.reverse.each do |link| %>
<option value=""<%= link.id %>"">
<%= link.posttime %> -- <%= link.title %>
</option>
<% end %>
</select>
</td>
</tr>
<% end %>"
What would be the code to replicate what you did? (I've tried, but after 5 hours, my head just hurts.)
Thanks.
Hi Chris,
Do you have any suggestion for multiple edit form pagination?
Thanks in Advance,
VK
You rock dude. Thanks a bunch!
Post a Comment
<< Home