Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails forms - When no checkboxes are checked, param is not included in POST

I have a Task model, which is joined in a many-to-many relationship with an Objective model.

I have a Task edit form where a user can associate any Objective with a Task via checkboxes. When a checkbox is checked, it should indicate an association between the Task and a particular Objective; when a checkbox is not checked, there should be no association. This should be persisted to the database when the form submits.

<%= form_for @task do |f| %>
  <% Objective.all.each do |objective| %>
    <%= check_box_tag :objective_ids, objective.id, @task.objectives.include?(objective), :name => 'task[objective_ids][]' %>
  <% end %>
  <%= f.button :submit %>
<% end %>

Updating a Task seems to work absolutely fine as long as one checkbox is checked by the user, but when the user does not check any checkboxes, the :objective_ids param (which is an array of Objective ids) is not included in the POST action at all. Because of this, when I do @task.update_attributes(params[:task]) in the controller, the Task's collection of Objectives is not updated (i.e. the Task should no longer have any Objectives associated with it, because no checkboxes were checked).

So how can I ensure the :objective_ids param is included in the POST, even if only as an empty array?

like image 501
XåpplI'-I0llwlg'I - Avatar asked Aug 23 '12 04:08

XåpplI'-I0llwlg'I -


1 Answers

Add hidden field above all checkboxes with empty value. It will be sent in case user didn't check any checkboxes.

<%= form_for @task do |f| %>
  <%= hidden_field_tag "task[objective_ids][]", nil %>
  <% Objective.all.each do |objective| %>
    <%= check_box_tag :objective_ids, objective.id, @task.objectives.include?(objective), :name => 'task[objective_ids][]' %>
  <% end %>
  <%= f.button :submit %>
<% end %>

Here is a good railscasts about this.
You may also want to check the source code for it.

like image 88
cutalion Avatar answered Oct 21 '22 16:10

cutalion