I don't think the fault is in ActionController. The params hash should echo whatever parameters are being passed from the browser. The browser sends an empty string, it's ActiveRecord's job to coerce the strings into more suitable objects depending on the attribute you're assigning to.
I'm okay with an empty string being coerced into nil for boolean attributes (for consistency). But I do think the :null => false setting is much more common in boolean attributes than any other type. Otherwise it's not a true boolean attribute (it can hold 3 states). Too often I've been bitten by a bug where null slipped into a boolean field and it didn't match a "false" search. Regards, Ryan On Aug 19, 4:58 am, Chris Cruft <[EMAIL PROTECTED]> wrote: > 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). > # Seehttp://dev.rubyonrails.org/ticket/5694for 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 -~----------~----~----~----~------~----~------~--~---
