Mio
Mio

Reputation: 1502

How to check if an array contains integers or a string of integers

I have a request from my api. The parameters can be an array like ["3456", "567564"] (form data) or "45643, 45645, 45645" (json). These parameters are sent directly to a sql request. I have to check if a user sent only integers; otherwise SQL will crash: > ERROR: invalid input syntax for integer: "8939f".

For the moment, I have this:

def valid_group_params?
  group_ids_to_add = params[:group]['group_ids_to_add']
  group_ids_to_remove = params[:group]['group_ids_to_remove']
  if group_ids_to_add && group_ids_to_remove
    group_ids = group_ids_to_add + group_ids_to_remove
    if group_ids.is_a? Array
      group_ids = group_ids * ","
    else
      group_ids = group_ids_to_add + ',' + group_ids_to_remove
    end
    group_ids.split(',').all? {|x| x !~ /\D/ }
  end
end

but I don't like it that much. Is there a better way to do it?

Upvotes: 0

Views: 2080

Answers (4)

Wayne Conrad
Wayne Conrad

Reputation: 107989

Use the global method Kernel#Integer:

Integer("123")    # => 123
Integer(123)      # => 123

This is much like #to_i, in that it will convert a string to an integer and leave an integer unchanged. However, unlike #to_i, #Integer will raise an error if its argument does not represent an integer:

Integer("abc")    # => ArgumentError: invalid value for Integer(): "abc"

Upvotes: 2

Cary Swoveland
Cary Swoveland

Reputation: 110675

I'm not sure if I understand the question, particularly after reading the other answers. Would this help?

def all_digits?(params)
  case params
  when Array
    params
  when String
    params.split /,\s+/
  else
    # raise exception
  end.all? { |e| e =~ /^\d+$/ }
end

to_add = params[:group]['group_ids_to_add']
to_remove = params[:group]['group_ids_to_remove']
to_add && to_remove && all_digits?(to_ad) && all_digits?(to_remove)

Case 1

to_add    = ["123", "456"]
to_remove = ["789", "0cat"]

to_add && to_remove && all_digits?(to_add) && all_digits?(to_remove)
  #=> ["123", "456"] && ["789", "0cat"] && true && false
  #=> false

Case 2

to_add    = "123", "456"
to_remove = "789", "0cat"
to_add && to_remove && all_digits?(to_add) && all_digits?(to_remove)
  #=> "123", "456" && "789", "0cat" && true && false
  #=> false

Upvotes: 3

shivam
shivam

Reputation: 16506

Simply use to_i to convert string into integer.

As per official doc:

Extraneous characters past the end of a valid number are ignored. If there is not a valid number at the start of str, 0 is returned.

Eg:

"45643".to_i
# => 45643
"8939f".to_i
# => 8939 
"99 red balloons".to_i 
# => 99

If even this is not sufficient, you can always use regex:

"some1221text"[/\d+/]
# => "1221"

Upvotes: 3

Juanjo Salvador
Juanjo Salvador

Reputation: 1093

Use to_i method.

foo = "3456"
foo.to_i

Upvotes: 2

Related Questions