Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

provide a more complete explanation about why the check_box generates…

… a hidden field, and document the problem with array-like parameters
  • Loading branch information...
commit ea40dc09a564ebc2b0034e3c1ae2c4daffe7e79b 1 parent 235cd21
@fxn fxn authored
Showing with 31 additions and 2 deletions.
  1. +31 −2 actionpack/lib/action_view/helpers/form_helper.rb
View
33 actionpack/lib/action_view/helpers/form_helper.rb
@@ -449,8 +449,37 @@ def text_area(object_name, method, options = {})
# assigned to the template (identified by +object+). It's intended that +method+ returns an integer and if that
# integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a
# hash with +options+. The +checked_value+ defaults to 1 while the default +unchecked_value+
- # is set to 0 which is convenient for boolean values. Since HTTP standards say that unchecked checkboxes don't post anything,
- # we add a hidden value with the same name as the checkbox as a work around.
+ # is set to 0 which is convenient for boolean values.
+ #
+ # === Gotcha
+ #
+ # The HTML specification says unchecked check boxes are not successful, and
+ # thus web browsers do not send them. Unfortunately this introduces a gotcha:
+ # if an Invoice model has a +paid+ flag, and in the form that edits a paid
+ # invoice the user unchecks its check box, no +paid+ parameter is sent. So,
+ # any mass-assignment idiom like
+ #
+ # @invoice.update_attributes(params[:invoice])
+ #
+ # wouldn't update the flag.
+ #
+ # To prevent this the helper generates a hidden field with the same name as
+ # the checkbox after the very check box. So, the client either sends only the
+ # hidden field (representing the check box is unchecked), or both fields.
+ # Since the HTML specification says key/value pairs have to be sent in the
+ # same order they appear in the form and Rails parameters extraction always
+ # gets the first occurrence of any given key, that works in ordinary forms.
+ #
+ # Unfortunately that workaround does not work when the check box goes
+ # within an array-like parameter, as in
+ #
+ # <% fields_for "project[invoice_attributes][]", invoice, :index => nil do |form| %>
+ # <%= form.check_box :paid %>
+ # ...
+ # <% end %>
+ #
+ # because parameter name repetition is precisely what Rails seeks to distinguish
+ # the elements of the array.
#
# ==== Examples
# # Let's say that @post.validated? is 1:
Please sign in to comment.
Something went wrong with that request. Please try again.