Decimals and commas when entering a number into a Ruby on Rails form

James picture James · Jun 30, 2011 · Viewed 14.3k times · Source

What's the best Ruby/Rails way to allow users to use decimals or commas when entering a number into a form? In other words, I would like the user be able to enter 2,000.99 and not get 2.00 in my database.

Is there a best practice for this?

-- Update ---

Does gsub work with floats or bigintegers? Or does rails automatically cut the number off at the , when entering floats or ints into a form? I tried using self.price.gsub(",", "") but get "undefined method `gsub' for 8:Fixnum" where 8 is whatever number I entered in the form.

Answer

panteo picture panteo · Feb 19, 2013

I had a similar problem trying to use localized content inside forms. Localizing output is relatively simple using ActionView::Helpers::NumberHelper built-in methods, but parsing localized input it is not supported by ActiveRecord.

This is my solution, please, tell me if I'm doing anything wrong. It seems to me too simple to be the right solution. Thanks! :)

First of all, let's add a method to String.

class String
  def to_delocalized_decimal
    delimiter = I18n::t('number.format.delimiter')
    separator = I18n::t('number.format.separator')
    self.gsub(/[#{delimiter}#{separator}]/, delimiter => '', separator => '.')
  end
end

Then let's add a class method to ActiveRecord::Base

class ActiveRecord::Base
  def self.attr_localized(*fields)
    fields.each do |field|
      define_method("#{field}=") do |value|
        self[field] = value.is_a?(String) ? value.to_delocalized_decimal : value
      end
    end
  end
end

Finally, let's declare what fields should have an input localized.

class Article < ActiveRecord::Base
  attr_localized :price
end

Now, in your form you can enter "1.936,27" and ActiveRecord will not raise errors on invalid number, because it becomes 1936.27.