I want to simply check if a returned value from a form text field is a number i.e.: 12 , 12.5 or 12.75. Is there a simple way to check this, especially if the value is pulled as a param
?

- 42,876
- 8
- 99
- 111

- 18,067
- 10
- 25
- 19
-
um, the only thing is that the code works for is_a_number? works with the only exception being .02, or .3 numbers.... – user211662 Jan 19 '10 at 19:22
-
7I much prefer this solution: http://stackoverflow.com/questions/5661466/test-if-string-is-a-number-in-ruby-on-rails/5661695 I don't know why so many people think a regexp would be better for that. – 2called-chaos Sep 17 '13 at 14:11
10 Answers
You can use
12.is_a? Numeric
(Numeric
will work for integers and floats.)
If it arrives as a string that might contain a representation of a valid number, you could use
class String
def valid_float?
true if Float self rescue false
end
end
and then '12'.valid_float?
will return true if you can convert the string to a valid float (e.g. with to_f
).
-
Sorry, this is Ruby on Rails ... Basically, I just want to be able to evaluate any input from the user whether it be .03 0.3, 2.2 THe latter two work, but I need to get the first input working :S – user211662 Jan 19 '10 at 20:22
-
10```Fixnum``` doesn't seem to work with floats. However, ```Numeric``` works fine. So ```1.234.is_a? Fixnum == false```, but ```1.234.is_a? Numeric == true```. – KurtPreston Nov 28 '12 at 15:35
-
This doesn't work with floats. Should use `1.1.is_a? Numeric` See http://stackoverflow.com/a/17668654/76486 – Brian Armstrong Jul 16 '13 at 05:29
-
2
-
@Salil obviously that will not work for you, `'12'` is a String. In that case check the string with Regex or any other possible solution. – edmundo096 May 27 '17 at 05:33
I usually just use Integer and Float these days.
1.9.2p320 :001 > foo = "343"
=> "343"
1.9.2p320 :003 > goo = "fg5"
=> "fg5"
1.9.2p320 :002 > Integer(foo) rescue nil
=> 343
1.9.2p320 :004 > Integer(goo) rescue nil
=> nil
1.9.2p320 :005 > Float(foo) rescue nil
=> 343.0
1.9.2p320 :006 > Float(goo) rescue nil
=> nil

- 612
- 7
- 10
-
3In ruby 2.6 you can also do the following: `Integer('343', exception: false) # 343` and `Integer('fg5', exception: false) # nil` ``` – Vlad Hilko Nov 30 '21 at 11:31
Just regexp it, it's trivial, and not worth thinking about beyond that:
v =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
(Fixed as per Justin's comment)

- 9,550
- 1
- 29
- 22
-
6In ruby, ^ and $ denote the beginning/end of a line, not of a string. This makes this ineffective to use as a means of sanitizing inputs (see http://guides.rubyonrails.org/security.html#regular-expressions). A better approach would be: `v.to_s =~ /\A[-+]?\d*\.?\d+\z/`. – Justin Aug 05 '13 at 14:34
-
This does not work for strings that represent exponential notation `irb(main):031:0> v = "0.7e1" => "0.7e1" irb(main):032:0> v =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/ => nil ` – Stefan Musarra Mar 08 '23 at 19:00
You can add a:
validates_numericality_of :the_field
in your model.
See: http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002172

- 11,587
- 11
- 51
- 66
Just convert string twice:
num = '12'
num == num.to_i.to_s
#=> true
num = '3re'
num == num.to_i.to_s
#=> false

- 1,104
- 12
- 17
-
Works not so bad with integers, but there are so many ways to fail if you want to follow this advice with floats (which is what the question asks about): `"7" == "7".to_f.to_s #=> false` ("7" vs "7.0") – David Stosik Oct 29 '16 at 07:50
-
-
you can also format both string using the "%" operator to guarantee that they both end in the same string – Jaacko Torus Jul 19 '20 at 20:41
I would suggest this one
def is_a_number?(str)
!!(Float(str) rescue false)
end
> is_a_number?(1)
=> true
> is_a_number?(1.1)
=> true
> is_a_number?('1')
=> true
> is_a_number?('1.1')
=> true
> is_a_number?('a')
=> false
> is_a_number?(nil)
=> false

- 9,096
- 3
- 39
- 43
irb(main):005:0> 1.1.is_a? Numeric
=> true
irb(main):006:0> 1.is_a? Numeric
=> true
irb(main):007:0> 'asd'.is_a? Numeric
=> false

- 19,707
- 17
- 115
- 144
-
10
-
How would you tackle the String conversion problem? OP states it's from an text field. – schlingel Nov 24 '16 at 14:10
There was answer with Kernel#Float
But this variant is used with exception: false
key and double bang to return boolean
class String
def number?
!!Float(self, exception: false)
end
end

- 12,025
- 4
- 33
- 56
I'd rather use regexp matching, for example:
irb(main):015:0> 12.5.to_s.match?(/^-?\d+(\.\d+)?$/)
=> true

- 2,157
- 19
- 18
String values always convert to 0 with .to_i
[14] pry(main)> 'Apple'.to_i > 0
=> false
[15] pry(main)> '101'.to_i > 0
=> true

- 1,929
- 18
- 15
-
What about edge cases? If the number is 0 or negative your test will give a false negative. – anonymous Mar 16 '15 at 09:59
-
Even worse '1AB2'.to_i would return 1 for something that is clearly not an Integer... – Thomas Bindzus Aug 24 '15 at 09:38