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