Forum: Ruby on Rails where would you put this parsing?

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-03-28 15:02
(Received via mailing list)
All floats that come from the front-end should be parsed robustly in
my app, where "robustly" is by the definition the method I paste
below :-).

The non-DRY way to do this is to add explicit code in each relevant
point in the actions where any of those possible values are expected.
I thought I could monkey patch AR::Base in environment.rb to be able
to declare in my models somthing like

   parse_as_float :foo, :bar

which would generate accessors that would call parse_float before
delegating to write_attribute.

But that smeels like view-stuff in the model layer. That's not a
problem for me, unless there is a cleaner solution. What do you think?

-- fxn

   def self.parse_float(n)
     return 0.0 if n.blank?
     n = n.dup

     # take sign and delete it, if any
     s = n[0] == ?- ? -1 : 1
     n.sub!(/^[-+]/, '')

     # we assume a dot or comma followed by zero or up to two digits
at the
     # end of the string is the decimal part
     d = n.sub!(/[.,](\d{0,2})$/, '') ? $1 : "0"

     # in the rest of the number any non-digit is ignored
     n.gsub!(/\D/, '')

     # done
     return (s*("#{n}.#{d}".to_f) rescue 0.0)
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-03-28 22:51
(Received via mailing list)
On Mar 28, 2007, at 3:01 PM, Xavier Noria wrote:

> which would generate accessors that would call parse_float before
> delegating to write_attribute.

For the archives, I finally wrote wrappers for the relevant
ActiveRecord::ConnectionAdapters::Column methods. The application
works automatically the way we need without touching a single line of

class ActiveRecord::ConnectionAdapters::Column
    class << self
      alias :original_value_to_decimal :value_to_decimal
      def value_to_decimal(v)
        if v.is_a?(String)
          # We try first our parsing because the original method always
          # returns a BigDecimal and there's no way AFAIK to know
          # the constructor ignored part of the string. For example
          # gives 1, whereas we want 1.3.

      # This method is called both when dates are set in the model, and
      # when dates are loaded from the database. So we let the original
      # parser do its job, and give a chance to ours if it fails.
      alias :original_string_to_date :string_to_date
      def string_to_date(v)
        original_string_to_date(v) || MyAppUtils.parse_date(v)

-- fxn
This topic is locked and can not be replied to.