views:

2433

answers:

4

I'm making a simple to-do list application to teach myself Ruby on Rails, however I've run into a problem. I have a simple form that lists to-do items with a check box to the left of them, and an "Update" button at the bottom, as so:

[ ] Do the dishes
[ ] Take out the garbage
[ ] Take over the world
( Update )

Each to-do item is a separate record in the database with a "completed" boolean field. I want the form to submit a list of checked-off item ids to an action in which I can set each item's "completed" field to true, which will hide them from the view.

I know how to make a form that references multiple models, but not one that references multiple records of the same model. Any tips?

Thanks!

+1  A: 

Why not use a remote function to update the database when an item is checked, and get rid of the update button altogether?

Jarrod
I'm considering that later on, but I want to get it functioning without any JS first, as it seems to make debugging a lot harder (or at least that's the impression I get) and at this point I'm liable to make a ton of stupid mistakes.
Grant Heaslip
A: 

Since you can include the ID for each record when you create your form you will want the controller to iterate through items in you post then find and update each of those records accordingly.

csexton
I think I see what you're saying; name each of the checkboxes (in a non-modal form_tag form) using the todo item's ID then iterate through the hash in the controller and modify the records accordingly? Are there any potential gotchas in this approach that I should keep in mind?
Grant Heaslip
+1  A: 

Wow. That is some timing. The item right before this question in my RSS reader is the latest railscast from Ryan Bates and it appears to cover exactly what you are asking.

srboisvert
That worked out nicely, thanks for the heads-up!
Grant Heaslip
+7  A: 

Railscasts is your friend!

http://railscasts.com/episodes/52-update-through-checkboxes

It's really simple:

# routes.rb
map.resources :tasks, :collection => { :complete => :put }

# tasks_controller.rb
def complete
  Task.update_all(["completed_at=?", Time.now], :id => params[:task_ids])
end

# views\tasks\complete.html.erb
<% form_tag complete_tasks_path, :method => :put do %>
  <ul>
  <% for task in @incomplete_tasks %>
    <li>
      <%= check_box_tag "task_ids[]", task.id %>
      <%= task.name %>
    </li>
  <% end %>
  </ul>
  <%= submit_tag "Mark as Complete" %>
<% end %>
Luke
Thanks Luke, this seems like what I'm looking for.
Grant Heaslip