validates_numericality_of and numbers with comma

validates_numericality_of will accept anything which is non-nil and
which can convert to a float and not return an error. It does it by
converting the value to a string and sending it to Kernel.Float. So
whatever Ruby's Kernel.Float can handle will pass validation.

Kernel.Float("123.45")
=> 123.45 # success

Kernel.Float("1,234.56")
=> ArgumentError # failure

Kernel.Float("123,45")
=> ArgumentError # failure

Kernel.Float("1.234,56")
=> ArgumentError # failure

So if you want to use validates_numericality_of you'll have to remove
the commas and/or replace them with periods. The best place to do that
is probably the before_validation callback. Off the top of my head,
maybe something like:

def before_validation
  # remove any commas or periods that preceed 3 digits
  self.some_value.gsub!(/[\.\,](\d{3})/, '\1')

  # replace any comma that preceeds the final 2 digits with a period
  self.some_value.gsub!(/\,(\d{2})$/, '.\1')
end

As others suggested, your other choice is to go with
validates_format_of or to write your own custom validation. Keep in
mind that this depends on what your database will accept too. If your
database won't accept the "foreign-format" then you'd be better off
converting it before you validate.

One possible regular expression might be:
(^\d{1,3}(\,\d{3})*(\.\d{2})?$|^\d{1,3}(\.\d{3})*(\,\d{2})?$|^\d+([\.
\,]\d{2})?$|^[\.\,]\d{2}$)

It allows for:
  - comma-separated digits optionally ending in a period and 2 digits
(1,234,567.89)
  - period-separated digits optionally ending in a comma and 2 digits
(1.234.567,89)
  - non-separated digits optionally ending in a period or comma and 2
digits (1234567.89 or 1234567,89)
  - a comma or period followed by 2 digits (.75 or ,75)

Writing good regular expressions is tricky, so test them extensively
before relying on them.

HTH,
Kevin Skoglund

http://www.nullislove.com