Validates_numericality_of and numbers with comma

Hi, i’ve a little problem, i’m using this validates to check if an input
is a number, it works with the dot, like 123.45, but actually i need
that it works also with numbers with comma, like 123,45.
Is there any simple way to do this (or maybe is there any option to
activate this check?) ?
thanks

On Oct 14, 2007, at 8:32 AM, Mix M. wrote:

Hi, i’ve a little problem, i’m using this validates to check if an
input
is a number, it works with the dot, like 123.45, but actually i need
that it works also with numbers with comma, like 123,45.
Is there any simple way to do this (or maybe is there any option to
activate this check?) ?
thanks

So, it’s not a real number, just numerical text with commas?

If so, use something like this instead (regex might need tweaking):

validates_format_of :name,
:with => /[0-9,]*/

– gw

Greg W. wrote:

So, it’s not a real number, just numerical text with commas?

If so, use something like this instead (regex might need tweaking):

validates_format_of :name,
:with => /[0-9,]*/

– gw

nope, it’s a real number.
the difference is that in the uk/usa (and probably others) format you
write something like 15.20, (eg. 15 dollars and 20 cent)… the italian
format is with the comma, so you will write 15,20…actually it would
be good also to change the 15,20 in 15.20 and then validate
i’ve tried with this: price = price.to_s.gsub(’,’, ‘.’).to_f if
price.to_s.include?(’,’)
it should works
so i’ve tried to put it in the before_save…but it doesn’t work, i
think that is because the validations are done before… so i’ve put it
in the validate method, but it doesn’t work neither, probably because
the validates_numericality_of is done before…so, where should have i
to put it? :frowning:
another thing i’ve tried it’s to take the code of
validates_numericality_of, write it in the application.rb and modify it,
but it seems that rails uses it’s own and not it (also in that method i
don’t know exactly where to put that control)

Mix M. –

No answer, but a possible clue…

I am having a similar problem; validates_numericality_of seems pretty
limited. But I think there are two issues you face:

  • localization of acceptable number formats (1,234.56 is right in US,
    not in Italy; 1.234,56 is right in Italy, not in US), and
  • implicit recognition of numeric formatting, or coersion of display
    formats between (to and from) integers, floats, decimals, and hey, how
    about currency, while we’re at it!

I think replacing validates_numericality_of with
validates_format_of :name :with => /[0-9],./ would accept any
format, but it’s not really complete (if would accept
123.4556,789.10,1 and other funky variants). You could write one or
more nasty regex’s to handle any particular local format, but that
would only get you so far: before adding to the database, it needs to
be coerced into a number.

I have been attempting to figure out how to use the model_formatter
plugin in order to allow users flexibility in entering numeric
(currency) data, but I haven’t had luck getting it to do what I want.
I want my :decimal model field to be presented (in forms, displays,
etc.) as currency, and automagically converted to proper numeric
format for the database. I am still getting my head around a lot of
this; perhaps you’ll find the model_formatter plugin useful. And if
you figure out how to get it to do what I want, please let me know :slight_smile:

Tom

ah,i’ve forgot… i need both, 12.34 and 12,34, but i think that with a
replace of the comma with the dot it should work…if i’ll find where to
put that replace ^^°

On 10/14/07, Mix M. [email protected] wrote:

– gw
think that is because the validations are done before… so i’ve put it

You can put your substitution code in before_validation instead of
before_save. I’m sure you can guess when it will be executed :slight_smile:

Pat

On Oct 14, 2007, at 2:00 PM, Mix M. wrote:

italian
another thing i’ve tried it’s to take the code of
validates_numericality_of, write it in the application.rb and
modify it,
but it seems that rails uses it’s own and not it (also in that
method i
don’t know exactly where to put that control)

When I’ve dealt with this in other languages, I’ve typically had the
luxury of user preferance settings so that the system knew it was
dealing with one numeric style or the other for both input and putput
formatting.

If there’s no way to determine a preset mode, the style can usually
be derived with these rules:

  • if there’s one period and no commas – US
  • if there’s one comma and no periods – Euro
  • if there’s one comma and one period, select the right most of the
    two, if it is a period – US, else Euro
  • if there’s > 1 commas and 1 period – US
  • if there’s > 1 periods and 1 comma – Euro

As far as the user input filter goes, I allow 0-9, periods, commas,
and currently symbols. That way there’s none of this lame “use
numbers and periods only” instruction nonsense. Then I use strip out
the characters I actually want. So for US mode that would 0-9 and
periods. For Italy that would be 0-9 and commas. This preserves
precision. I strip out the thousands separators so the data can be
cast to decimal and stored, etc. Then I format it on output.

Whether Rails has tools built-in for that I don’t know, but it’s not
too bad to build yourself, and once you’ve done it, you always have it.

– gw

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!(/.,/, ‘\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 S.

http://www.nullislove.com

Hi,

I’ve got a similar problem - I want to allow the customer to enter $ and
, in number fields.

validates_numericality_of fails if you start with a £ - fair enough.

validates_format_of doesn’t seem to work - I think the value has been
converted to a number for this is checked and therefore it is too late.

before_validation seems the obvious answer.

Using the below code…

def before_validation
puts “#{self.price}”
self.price = self.price.to_s.gsub(/[^\d.]/, “”).to_i
puts “#{self.price}”
end

If I enter 999, then it correctly outputs 999 twice.

If I enter £999, then it outputs 0 twice - what!?

So I presume it has converted to a number before, my before_validation.

Anyone got aany suggestions?

I am really stunned that rails has such difficulty with something that
seems such a common problem - flexible user input.

Thanks,

James

Pat M. wrote:

On 10/14/07, Mix M. [email protected] wrote:

– gw
think that is because the validations are done before… so i’ve put it

You can put your substitution code in before_validation instead of
before_save. I’m sure you can guess when it will be executed :slight_smile:

Pat