About HTML attributes with the value 'false'

I’m puzzled by this latest commit:

“Tag helper should output an attribute with the value ‘false’ instead of omitting the attribute, if the associated option is false but not nil.”

http://github.com/rails/rails/commit/4e9abdd7f1b4e05f8d1b50ddaa080b3ff63b92d9

What was the reason for this? How does it help in HTML? Thanks

It's because Rails 2.2 changed the way empty strings are mapped to
boolean model attributes.

Migration:
  create_table :people do |t|
    t.boolean :is_alien, :null => false
  end

Rails 2.1:
  p = Person.new(:is_alien => "")
  p.is_alien # => false
  p.save # => true

Rails 2.2:
  p = Person.new(:is_alien => "")
  p.is_alien # => nil
  p.save # => StatementInvalid: value for is_alien may not be
null in INSERT statement!

In my controller I have this:
  def new
    @person = Person.new
    @person.is_alien = false
  end

  def create
    @person = Person.new(params[:person])
    @person.save
  end

In the 'new' view:
  <% form_for @person do |f| %>
    <%= f.hidden_field :is_alien %>

Before this commit, the hidden_field helper would output:
  <input type="hidden" name="person[is_alien]" />
As you can see, there's no "value" attribute. Upon submitting the
form, @person.is_alien would be set to nil instead of the expected
false, causing an SQL error. This is solved by making hidden_field
output value="false":
  <input type="hidden" name="person[is_alien]" value="false" />

Thanks Koz for a brief and Hongli for more detailed explanation, but I don’t think you got my question right.

You guys are talking about (hidden) textual form controls that map to booleans. That’s fine. I’m talking about HTML attribute serialization in general, meaning everything besides textual form controls mapping to booleans, and why I think this commit should be reverted. This is the reason:

<% tag :input, :type => “checkbox”, :checked => false %>

Who here thought that this creates a text input that isn’t checked? Well, you thought wrong. This generates an initially checked box.

  <% tag :input, :type => "checkbox", :checked => false %>
Who here thought that this creates a text input that isn't checked? Well,
you thought wrong. This generates an initially checked box.

OK, I now follow you. A patch to fix this would be appreciated :slight_smile:

Good point. This has been fixed in
http://github.com/rails/rails/commit/0f89ed5636f69c7ae75f99ca2a613b1918de5f95

I've registered 'checked' as a boolean HTML attribute so that it
doesn't get outputted when its value is false. If you encounter more
problems, then please suggest more attributes to register as boolean
HTML attributes.