The scenario that you mention is a classic one of empty strings being
returned from forms.  And the problem is
bigger than just booleans.  It also applies to strings, numbers and
lists.

In the scenario Josh mentions, a boolean field should have the empty
string or a blank string coerced to false (or nil) long before it gets
saved by ActiveRecord.

Putting the burden on ActiveRecord to massage the crap it is handed
into something meaningful seems out
of place.  Why not fix the problem at the source and get
ActionController to return meaningful values from empty form fields?

-1 for getting ActiveRecord to bail out ActionController with coercion
of empty strings and blanks.

As for the coercion of non-numerics objects, I agree that "1" seems
totally outrageous.  I would hope for the coercion to use to_i/to_f
conventions and raise an exception when they fail.

+1 for fixing/removing the coercion of non-numeric objects beyond a
simple to_i/to_f depending on the field type.

-Chris

PS - Here is some code I have in ApplicationController that attacks
the empty string problem at the source.  It could be cleaned up with
"returning" and other recent goodness:

  # Coerce empty string values in hash -particularly useful for HTTP
POSTed forms.  Values are coerced based on the attrs
  # mapping of params keys (attrs keys) to coerced values (attrs
values).
  # See http://dev.rubyonrails.org/ticket/5694 for background
  def coerce_empty_strings(params_hash, attrs = {})
    return unless params_hash
    params_hash.inject(HashWithIndifferentAccess.new) do |h,(k,v)|
      h[k] = (v.is_a?(String) && v.empty?) ? attrs[k.to_sym] : v
      h
    end
  end

On Aug 19, 1:40 am, Josh Susser <[EMAIL PROTECTED]> wrote:
> This may seem a minor issue, but I think it's worth a bit of  
> discussion to get it right.  Let me start with the use case that led  
> me smack into the issue.
>
> Start with some model that has a boolean field that can be nil/null.  
> Create a view with a form that uses a select box to set the field's  
> value, and set :include_blank => true.  The obvious assumption is that  
> if you select blank (as opposed to Yes/1/true or No/0/false), the  
> field value will be saved as nil/null.  Not so - it is saved as 0/
> false.  This has the weird behavior of the select box showing the  
> false choice when you select blank and get bounced back for a second  
> try at the form.
>
>     create_table :widgets do |t|
>       t.string  :name
>       t.boolean :fancy
>     end
>
>     w = Widget.create(:name => "weather", :fancy => true)
>     w.fancy  # => true
>     w.update_attributes(:fancy => nil)
>     w.fancy  # => nil
>     w.update_attributes(:fancy => "")
>     w.fancy  # => false
>
> It's not too much trouble to patch ActiveRecord to change it so that  
> setting a boolean field to a blank string gets saved as NULL in the  
> database instead of 0.  The question is: what is the desired  
> behavior?  More specifically, when should the value be coerced, with  
> special consideration to the case when the field doesn't allow a nil/
> NULL value?
>
> I think the answer is that blank values should always be coerced to  
> nil in memory, even when the field is created with :null => false.  
> This is consistent with how integer fields are handled.  You can have  
> a nil value in memory, and the db will barf when you try and save it  
> as NULL.  AR expects you to use a validation to catch that and give  
> the user another shot at the form.  However...  there is what looks to  
> me like a bug in AR where assigning a blank-but-not-empty string to an  
> integer field has a different result from assigning an empty string or  
> nil.  An empty string is coerced to nil, but a string of one or more  
> whitespace characters is coerced to 0.  It's also easy to fix it so  
> that all blank strings are coerced to 0, and I think that would be the  
> best thing to do.  But I wonder if anyone out there might be relying  
> on this behavior.  There are only 2 tests that break when this change  
> is made (in validations_test.rb).
>
> By the way, strings representing integers are coerced to their correct  
> values, but non-numeric objects like arrays and hashes are coerced to  
> 1.  WTF?  Why is that useful?
>
> I was going to create a ticket with a patch for this stuff to refer  
> to, but the code is sitting on a computer at work so that won't happen  
> until the morning (sorry, Pratik).
>
> To summarize:
>
> I propose that all blank strings should be coerced to nil, for both  
> boolean and integer fields.  Any issues with that?  Anyone know if  
> they are relying on that behavior?
>
> --
> Josh Susserhttp://blog.hasmanythrough.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to