I have a form that displays whether tasks are complete or not. You can check the box to set the model's :is_complete attribute to true, and check it again to set it as false. Or so that's how it's supposed to work. I can mark tasks as complete, hit the Update button, and the tasks get marked as complete just fine. But when I try to uncheck the tasks afterwards, nothing gets sent to the update action until I hit the update button again, when they finally get marked as incomplete.
Form
<%= form_tag '/day_tasks/update', :method => :put do %>
<% @day_tasks.each do |day_task| %>
<%= check_box_tag "day_tasks[]", day_task.id, day_task.is_complete? %> 开发者_如何转开发
<%= day_task.task.content %><br />
<% end %>
<%= submit_tag "Update" %>
<% end %>
Update action
def update
params[:day_tasks] ||= []
params[:day_tasks].each do |x|
DayTask.find(x).toggle(:is_complete).save
end
redirect_to day_tasks_path
end
I'm pretty sure the issue is with the logic behind displaying whether or not a box is checked ( day_task.is_complete? ) because if I remove that snippet of code, although boxes never appear checked, the tasks are checking and unchecking perfectly fine on the back end. It's only when this snippet is included that I run into the problem of nothing being sent after I hit Update a second time. Any ideas on why this is occurring?
The problem is that a not-checked checkbox will never be sent to the server.
There's a trick: Add a hidden input field with the same name right before the check_box_tag
and give it the false value like:
<%= form_tag '/day_tasks/update', :method => :put do %>
<% @day_tasks.each do |day_task| %>
<%= hidden_field_tag "day_tasks[#{day_task.id}]", "0" %>
<%= check_box_tag "day_tasks[#{day_task.id}]", "1", day_task.is_complete? %>
<%= day_task.task.content %><br/>
<% end %>
<%= submit_tag "Update" %>
<% end %>
So now if the check box is not checked, the value will be 0 (false) when the check box is checked, the checkbox "overwrites" the hidden field and sets the value to 1 (true)
You have to adapt your update action since you will get a hash like:
day_tasks[task_id] = 0/1 (not completed / completed)
your update action:
def update
params[:day_tasks] ||= {}
params[:day_tasks].each do |task_id, completed|
DayTask.find(task_id).update_attribute(:is_complete, completed)
end
redirect_to day_tasks_path
end
精彩评论