From ea40dc09a564ebc2b0034e3c1ae2c4daffe7e79b Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 17 Jun 2008 21:59:41 +0200 Subject: provide a more complete explanation about why the check_box generates a hidden field, and document the problem with array-like parameters --- actionpack/lib/action_view/helpers/form_helper.rb | 33 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 7d85799038..6348ff5f49 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -449,8 +449,37 @@ module ActionView # 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: -- cgit v1.2.3