2

I'm on Rails 3.0.x, Ruby 1.9.2 and needs a way to test for params that may or may not exists, e.g.,

params[:user] #exists
params[:user][:login] #may not exist

What's the proper Ruby syntax for the 2nd check so it doesn't barf?

Johnny Klassy
  • 1,650
  • 5
  • 16
  • 22
  • 1
    duplicated: http://stackoverflow.com/questions/4371716/looking-for-a-good-way-to-avoid-hash-conditionals-in-ruby – tokland Oct 26 '11 at 22:41

3 Answers3

2

Try following:

params.has_key? :user #=> true because exists
params[:user].has_key? :login #=> true if exist otherwise false
WarHog
  • 8,622
  • 2
  • 29
  • 23
  • Nice suggestion but that doesn't work because `params[:user]' first returns it as as string in which case it is no longer a hash and hence no `has_key?` method. – Johnny Klassy Oct 26 '11 at 22:38
1

@WarHog has it right, pretty much. It's very unusual for an item in params to sometimes return a string but other times return a Hash, but regardless you can handle that easily enough:

if params.has_key?(:user) && params[:user].respond_to?(:has_key?)
  do_something_with params[:user][:login]
end

Instead of respond_to? :has_key? you could also do respond_to? :[] or just is_a? Hash. Mostly a matter of preference.

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
0

You would just get nil in the second case.. that shouldn't be a problem, no? e.g. params[:user][:login] just returns nil, which evaluates to false if the :user entry exists in the first Hash.

However if the nesting would be one or more levels deeper, and the missing hash entry was somewhere in the middle, you would have problems. e.g.:

params[:user][:missing_key][:something]

in that case Ruby would try to evaluate nil[:something] and raise an exception

you could do something like this:

begin
  x = params[:user][:missing_key][:something]
rescue
  x = nil
end

... which you could further abstract...

Tilo
  • 33,354
  • 5
  • 79
  • 106