+1 for "when :integer then value.to_i" And if I get up on the wrong side of the bed, then I might propose "when :integer then value"
Honestly, having the persistence layer guess at what is "intended" to be stored seems like a losing proposition. What's next? Guessing that for a boolean field "Nein" means false and "Oui" means true and that for an integer field that "Two" means 2 and "a lot" means 3? ActiveRecord is doing two jobs: modelling and persisting. You could make a case for AR modelling being a good place to address the coercion problem... but not generically. If you want to solve the problem in AR, then let's give the user the ability to model coercion rules as well. But ultimately, WHEREVER the modelling of coercion is performed, it needs to be available right from the start of processing in the controller action. And coercion rules/modelling needs to be available for input data that it is not persisted (or at least not by an ActiveRecord model). A good solution might be a reverse presenter (to use Josh's term) that can be modelled independently, with AR automatically generating a default reverse presenter bound to each model class. More complicated Reverse Presenters could accept multiple AR models and their associations as well as manually managed attributes. A ReversePresenter would be instantiated with the request's params at the start of a controller action. It's all downhill from here... Of course it's worth considering combining the Reverse Presenter and the classic Presenter into one class. That might help with building some enthusiasm for the idea and it would probably reduce the amount of modeling required. On Aug 19, 12:23 pm, Josh Susser <[EMAIL PROTECTED]> wrote: > On Aug 19, 2008, at 4:58 AM, Chris Cruft 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? > > I think the problem with that approach stems from the fact that form > data is submitted as untyped strings. There's no way to look at the > string "1,100" and guess if that means the string itself, the integer > 1100, or the list [1, 100]. Currently ActiveRecord does the best it > can to convert string data from forms into appropriate values for > fields, and sometimes it falls over (bug or flawed design?). > > I see three paths we can take to improve things: > > 1) incrementally improve ActiveRecord to more sensibly process string > inputs and convert to the correct data type for fields, i.e. blank > string handling > > 2) significantly alter ActiveRecord for more flexible and targeted > processing of string inputs > > 3) create some kind of middle-man object to assist in converting form > input strings to correct data types > > Path 1 seems like a good approach in the short term, and there seems > to be little reason not to fix obvious errors in how ActiveRecord > operates. Even if we do something else, it doesn't seem like a good > idea to remove this functionality from AR, since that would break > virtually *every* Rails app in existence. > > Path 2 could be interesting as a generic approach. I've done exactly > this in specific situations often before - e.g. I fake up a tags_list > accessor on the model to allow user input of a list of tags like > "rails, ruby, sighting". You can of course do this without any > special support, but perhaps a bit of syntactic sugar could improve > things. > > Path 3 sounds great in theory. It's like a presenter that runs in > reverse too. But I wonder if separating the processing of form input > data into a separate object is going to be worth the effort. I'd be > interested in seeing someone's proposal for what that might look like > (unfortunately I have a few other science experiments higher in my own > priority queue right now). > > In the mean time, I propose Path 1 as the simplest thing that could > possibly work to fix the use case where submitting forms with blank > values gives a non-nil value in the field. > > > -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. > > That's just what it does (schema_definitions.rb:65): > > when :integer then value.to_i rescue value ? 1 : 0 > > I'm still puzzling over that one, especially since `value` will never > be nil (thanks to a test a few lines above). > > -- > 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 -~----------~----~----~----~------~----~------~--~---
