#198
Jan 25, 2010

Edit Multiple Individually

Use checkboxes to edit multiple records in one form, where each one has an individual set of form fields.
Tags: views forms
Download (33.6 MB, 13:53)
alternative download for iPod & Apple TV (19.8 MB, 13:53)

Resources

# products_controller.rb
def edit_individual
  @products = Product.find(params[:product_ids])
end

def update_individual
  @products = Product.update(params[:products].keys, params[:products].values).reject { |p| p.errors.empty? }
  if @products.empty?
    flash[:notice] = "Products updated"
    redirect_to products_url
  else
    render :action => "edit_individual"
  end
end

# routes.rb
map.resources :products, :collection => { :edit_individual => :post, :update_individual => :put }
<!-- views/products/index.html.erb -->
<% form_tag edit_individual_products_path do %>
  <table>
    <tr>
      <th></th>
      <th>Name</th>
      <th>Category</th>
      <th>Price</th>
    </tr>
  <% for product in @products %>
    <tr>
      <td><%= check_box_tag "product_ids[]", product.id %></td>
      <td><%=h product.name %></td>
      <td><%=h product.category.name %></td>
      <td><%= number_to_currency product.price %></td>
      <td><%= link_to "Edit", edit_product_path(product) %></td>
      <td><%= link_to "Destroy", product, :confirm => 'Are you sure?', :method => :delete %></td>
    </tr>
  <% end %>
  </table>
  <p>
    <%= select_tag :field, options_for_select([["All Fields", ""], ["Name", "name"], ["Price", "price"], ["Category", "category_id"], ["Discontinued", "discontinued"]]) %>
    <%= submit_tag "Edit Checked" %>
  </p>
<% end %>

<!-- views/products/edit_individual.html.erb -->
<% form_tag update_individual_products_path, :method => :put do %>
  <% for product in @products %>
    <% fields_for "products[]", product do |f| %>
      <h2><%=h product.name %></h2>
      <%= render "fields", :f => f %>
    <% end %>
  <% end %>
  <p><%= submit_tag "Submit" %></p>
<% end %>

<!-- views/products/_fields.html.erb -->
<%= f.error_messages :object_name => "product" %>
<% if params[:field].blank? || params[:field] == "name" %>
<p>
  <%= f.label :name %><br />
  <%= f.text_field :name %>
</p>
<% end %>
<% if params[:field].blank? || params[:field] == "price" %>
<p>
  <%= f.label :price %><br />
  <%= f.text_field :price %>
</p>
<% end %>
<% if params[:field].blank? || params[:field] == "category_id" %>
<p>
  <%= f.label :category_id %><br />
  <%= f.collection_select :category_id, Category.all, :id, :name %>
</p>
<% end %>
<% if params[:field].blank? || params[:field] == "discontinued" %>
<p>
  <%= f.check_box :discontinued %>
  <%= f.label :discontinued %>
</p>
<% end %>

RSS Feed for Episode Comments 39 comments

1. Joseph Silvashy Jan 25, 2010 at 00:06

This is awesome, I'd like to se this combined with Formtastic, thanks for the awesome screencast!


2. senthil Jan 25, 2010 at 00:24

+1 for combination with Formtastic.


3. Stingy Jan 25, 2010 at 00:34

i love formtastic. would be great if it is standard like ryans nifty generators.


4. Branden Jan 25, 2010 at 00:46

Thanks for this screencast Ryan. This definitely enhances the functionality of episode #165. These casts on dealing with multiple edits, models, nested_attributes etc are extremely helpful for my self.newbie to wrap my head around these things.

Much appreciated,

Branden


5. waqas Jan 25, 2010 at 01:59

This is xcellent screencast. Keep up the good work Ryan. I will be using this in my upcomgin RoR project.


6. Claudio Jan 25, 2010 at 05:41

Thanks for this screencast Ryan.


7. andresgutgon Jan 25, 2010 at 05:46

+1 for combination with Formtastic.

Thanks for your work!


8. Steve Jan 25, 2010 at 07:49

I love how you make the techniques in each screencast seem so simple, as in, "Why didn't I think of that!".

I think it inspires new guys like myself to sit back and look for a simple solution instead of over thinking a problem, which I tend to do all the time.

More times than not the solution is simple; it just takes a better understanding of the wonder that is rails!

Thanks for your work Ryan. I greatly appreciate it.


9. Zoga Jan 25, 2010 at 08:23

great episode, as usual :)
+1 for combination with Formtastic.


10. GGC Jan 25, 2010 at 10:37

That's a great episode. Thanks a lot Ryan. It's very useful and perfect to put on practice on every rails project or any project. I like Ruby more. Simple and elegant. Thanks again Ryan.


11. René Jan 25, 2010 at 11:13

Very nice episode, thanks a lot!


12. B Jan 25, 2010 at 11:42

You said the route would best be a GET and I agree; why not add :method => :get on the form to make it so?


13. Patrick Jan 25, 2010 at 15:41

Favorite episode to date! Thanks.


14. Thomas Jan 25, 2010 at 16:46

Ryan,

Love the screenscasts! Can I recommend you do one on an administrative tool like Typus (http://intraducibles.com/projects/typus) or something similar. I have used Typus for the first time recently and found it extremely helpful in getting up and running quickly. It does require some configuration of YAML files but you also have the ability to override pretty much everything.

Keep up the good work! Thanks.


15. Vincent Bray Jan 26, 2010 at 04:16

Awesome as ever. Perhaps someone would be kind enough to document f.error_messages in the API docs?


16. Hubert Łępicki Jan 26, 2010 at 08:23

I watched it yesterday and was thinking it's trival, useless and will never use it. Or not soon.

And now it looks like it's perfect solution for my today's problem at work. Man, how do you do it?


17. Judd Jan 26, 2010 at 11:34

Thanks Ryan! At times I feel like we work together. ;)


18. Nisse Jan 26, 2010 at 14:25

I cannot understand why you wouldn't do a GET request instead. I mean, sure it will be a long query-string but that also means you could bookmark edit pages. If you keep track of certain products and update them daily that would be excellent.

Or is it really necessary with POST like you said?


19. Martin Jan 28, 2010 at 04:08

One of my favorite episodes.


20. pduersteler Jan 28, 2010 at 08:10

also +1 for formtastic


21. CCNA Jan 28, 2010 at 19:21

Keep up the good work! Thanks.


22. Zoga Jan 29, 2010 at 16:04

Would be interesting to combine webforms2 with this. Following example is screaming at this screencast :)

http://webforms2.googlecode.com/svn/trunk/testsuite/003.html


23. davis Feb 05, 2010 at 20:11

Hmm, this line in the controller feels a little risky:

Product.update(params[:products].keys, params[:products].values)

"params" is a Hash (actually a subclass of Hash, HashWithIndifferentAccess), and its "keys" and "values" methods return arrays in no particular order. It's probably not a good idea to assume they'll pair up properly every time. Even if it works in practice, it probably exploits an undocumented fact about the Hash implementation.

Something like the following might be more bulletproof. It removes the assumptions but does basically the same thing:

keys = params[:products].keys
values = keys.map {|k| params[:products][k]}

Aside from that, thanks for all the helpful 'casts.


24. buy terracotta warriors Feb 08, 2010 at 00:00

I watched it yesterday and was thinking it's trival, useless and will never use it. Or not soon.


25. paese Feb 11, 2010 at 05:39

very nice one, thanks!

+1 for combination with formtastic
+1 for usually using formtastic in railscasts ;-)


26. Mike_S Feb 14, 2010 at 08:56

Ryan,

I haven't tried this yet, but is this the solution to completing the "survey series" (#196, #197) ?

Or do you have something else ?

If so, I'd love to see a final episode to complete the survey app, i.e. where a user can answer the questions on the survey.

Mike


27. Mike_S Feb 15, 2010 at 12:15

Ryan,

If you click 'Edit Checked' without anything checked you get a walkback:

Couldn't find Product without an ID

How do you trap that error / post an error message?

Mike


28. MIke_s Feb 15, 2010 at 13:27

Ryan,

I tried the following code, the flash gets displayed, but the 'Product.find' is still getting executed resulting in the error :
"Couldn't find Product without an ID"

begin
rescue params[:product_ids].empty?
  logger.error("No products selected for 'Edit Selected'" )
    flash[:notice] = "Nothing selected for 'Edit Selected' action"

redirect_to products_path
end

@products = Product.find(params[:product_ids])


29. David Feb 21, 2010 at 12:29

Awesome! Very handy!


30. mwicks1968 Feb 26, 2010 at 03:52

Ryan - Great Cast once again!

A Question: How would you implement a "mass edit" facility?

What I mean to say is: say you had an attribute which you want to set to the same thing for ALL rows selected on the front form. How do you do this with a single control?

Cheers


31. mwicks1968 Mar 03, 2010 at 04:15

In reply to myself, I checked out Episode 165

Result!


32. mwicks1968 Mar 03, 2010 at 07:52

Another question:

How do you implement a check box that checks all the check boxes (if you know what I mean!)?

Cheers


33. Ohad Mar 14, 2010 at 23:51

how can I use nested_attributes with this approch? e.g. http://stackoverflow.com/questions/2445097/accepts-nested-attributes-with-model-update-for-multiple-models


34. Gang Mar 23, 2010 at 08:18

It's a great!


35. terracotta warriors Apr 15, 2010 at 00:06

it's useful


36. Gam Apr 16, 2010 at 10:12

Oh my, this is the third time Ryan describes EXACTLY what I was looking for...
kudos kudos kudos!


37. Ayırma Büyüsü May 26, 2010 at 02:52

great post,i hope you update asap


38. The Diet Solution Program May 31, 2010 at 06:07

Hey this is really nice information. I was looking for something similar like this. Thanks for this useful information.


39. nike dunk sb Jul 04, 2010 at 23:50

Your article is very interesting, I have introduced a lot of friends to see this article content, there will be a lot of attractive people to enjoy, I want to thank you for this article.


40. candys Jul 12, 2010 at 01:11

I love it,Excellent article


41. olded Jul 12, 2010 at 01:48

All I'm looking for a site on a very large and beautiful on this site are subject to all of you very
thanks


42. fast weight loss Jul 12, 2010 at 23:22

Code is too complicated, could be more simpler


43. home loans Jul 12, 2010 at 23:27

Thanks, it helps me


44. cheap car insurance Jul 12, 2010 at 23:31

There is no other way to solve


45. bocek ilaclama Jul 14, 2010 at 02:19

böcek ilaçlama şirketi tuba mühendislik


46. arac muayene Jul 14, 2010 at 02:20

muayene ilemleri araba muayenesi hizmetleri


47. yeni oyunlar Jul 19, 2010 at 01:46

That's a great episode. Thanks a lot Ryan. It's very useful and perfect to put on practice on every rails project or any project. I like Ruby more. Simple and elegant. Thanks again Ryan.


48. Car Pictures Jul 31, 2010 at 06:29

Code is too complicated, could be more simpler


49. Interior Design Jul 31, 2010 at 06:30

Hey this is really nice information. I was looking for something similar like this. Thanks for this useful information.


50. fade watches Aug 02, 2010 at 00:36

Dear friends, our web site provides a variety of cheap price <a href=http://www.watchesky.com/omega-watches>fade omega watches</a> , welcome your arrival,just click here http://www.watchesky.com/ .


51. travel Aug 02, 2010 at 06:34

Good code, interesting solution. Very useful, thanks


52. replica jerseys Aug 03, 2010 at 20:06

nice article, thanks for sharing this with us here!!!


53. Roy @ China Tours Aug 05, 2010 at 19:40

Thanks for sharing this code! Trying to find something like this for a while. It's very useful.


55. fadewatches Aug 06, 2010 at 18:04

I am a fanatic watch collection, especially the well-known watches, you also can do, just click on my name!!!!!!!!


56. UGG Boots on sale Aug 10, 2010 at 18:53

Gooooooooooooooooooood luck ~~!!


57. lower ab exercises for men Aug 14, 2010 at 06:00

I am a fanatic watch collection, especially the well-known watches, you also can do, just click on my name!!!!!!!!


58. replica nfl jerseys Aug 15, 2010 at 20:05

Please tell me it worked right? I dont want to sumit it again if i do not have to! Either the blog glitced out or i am an idiot, the second option doesnt surprise me lol. thanks for a great blog!


59. Rip Blu-ray for Mac Aug 18, 2010 at 01:49

Thanks,it's so good.
suport!


60. Wholesale hats Aug 20, 2010 at 20:13

Fantastic Read! Looking forward to more! Bookmarked the site and will be back again!


61. converse all star Aug 20, 2010 at 20:47

love converse all star,love yourself.High quality low price.It's fit for you.


62. omega watches Aug 23, 2010 at 02:38

  winni2078 08 23
http://www.juicycouture4u.com/
http://www.newstyleomega.com/
http://www.juicycouture4u.com/Juicy-Couture-Handbag.html
http://www.juicycouture4u.com/Juicy-Couture-Tracksuits.html
http://www.newstyleomega.com/
http://www.newstyleomega.com/
http://www.newstyleomega.com/


63. lily Aug 23, 2010 at 23:23

Any member of your group can post to your trip blog. This is a great way to share information with your team and your
supporters.<b><a href=http://www.hzzxdq.net>power strip</a></b> |<b><a href=http://www.jdxpwj.cn/booster-cable>booster cable</a></b> |
<b><a href=http://www.jdxpwj.cn/tow-rope>tow rope</a></b> |<b><a href=http://www.jdxpwj.cn/ratchet-tiedown>ratchet tiedown</a></b>


64. jordan retro shoes Aug 23, 2010 at 23:26

The blog article very surprised to me! Your writing is good. In this I learned a lot! Thank you! I like this blog very much for nice coding tutorial. Great article, especially the layout of the models. Could you do one on how to extend active merchant so that we can all contribute to the code base?


65. cheap clothes Aug 24, 2010 at 19:29

David Heinemeier Hansson..thanks


66. PDF to Images Converter Aug 24, 2010 at 22:59

Some times, to a certain need, we have to convert PDF to image for enjoyment.


67. Wholesale Electronics Aug 25, 2010 at 01:12

Discount Wholesale Electronics, Wholesale Cell Phones, Electronic Gadgets and More from the Best Dropship Wholesaler


68. louis vuitton shoes Aug 26, 2010 at 23:21

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


69. rap Aug 29, 2010 at 09:00

Thank you wery much


70. Seivan Aug 29, 2010 at 15:34

I got this made with formtastic if anyone is interested.


71. snow boots Aug 30, 2010 at 20:33

There is no other way to solve


72. louis vuitton sunglasses Sep 01, 2010 at 21:21

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source