How to test if parameters exist in rails

209,540

Solution 1

You want has_key?:

if(params.has_key?(:one) && params.has_key?(:two))

Just checking if(params[:one]) will get fooled by a "there but nil" and "there but false" value and you're asking about existence. You might need to differentiate:

  • Not there at all.
  • There but nil.
  • There but false.
  • There but an empty string.

as well. Hard to say without more details of your precise situation.

Solution 2

I am a fan of

params[:one].present?

Just because it keeps the params[sym] form so it's easier to read.

Solution 3

use blank? http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

unless params[:one].blank? && params[:two].blank?

will return true if its empty or nil

also... that will not work if you are testing boolean values.. since

>> false.blank?
=> true

in that case you could use

unless params[:one].to_s.blank? && params[:two].to_s.blank?

Solution 4

You can write it more succinctly like the following:

required = [:one, :two, :three]
if required.all? {|k| params.has_key? k}
  # here you know params has all the keys defined in required array
else
  ...
end

Solution 5

Simple as pie:

if !params[:one].nil? and !params[:two].nil?
  #do something...
elsif !params[:one].nil?
  #do something else...
elsif !params[:two].nil?
  #do something extraordinary...
end
Share:
209,540

Related videos on Youtube

Darren
Author by

Darren

Updated on November 16, 2021

Comments

  • Darren
    Darren over 2 years

    I'm using an IF statement in Ruby on Rails to try and test if request parameters are set. Regardless of whether or not both parameters are set, the first part of the following if block gets triggered. How can I make this part ONLY get triggered if both params[:one] and params[:two] is set?

    if (defined? params[:one]) && (defined? params[:two])
     ... do something ...
    elsif (defined? params[:one])
     ... do something ...
    end
    
    • mu is too short
      mu is too short about 10 years
      @Nakilon: Given that params is a Rails controller method (that happens to return a HashWithIndifferentAccess), it is about Rails.
  • Jacob Relkin
    Jacob Relkin about 13 years
    @sawa It's not possible to pass a nil parameter. If the parameter exists, it will be an empty string.
  • mu is too short
    mu is too short about 13 years
    @Jacob: There's no guarantee that params hasn't been pre-processed before we get to where we're checking what's in it. Hence my list of possible special cases to check. Best to say exactly what you mean IMHO.
  • EmFi
    EmFi about 13 years
    While this covers the case where both parameters are defined. It does not cover the case where one of them evaluates to false.
  • Dominik Grabiec
    Dominik Grabiec about 13 years
    That doesn't check if the parameter is there but actually set to nil.
  • Jacob Relkin
    Jacob Relkin about 13 years
    @Daemin In reality though, a parameter cannot be set to nil in a request header. It's either nil or a string.
  • Dominik Grabiec
    Dominik Grabiec about 13 years
    Yes but as other people have stated, it might get modified by something else, a plugin, gem, or your own code, or just fails to parse for some bizarre reason.
  • Inkling
    Inkling almost 10 years
    Or present? which returns the opposite of blank?. So you could turn that unless into an if if you wanted to.
  • Orlando
    Orlando almost 10 years
    @Inkling that works, but an inline unless it's ok. But yeah, I like better if with present?
  • FloatingRock
    FloatingRock over 9 years
    has_key? is now deprecated. Use Hash.key? instead
  • mu is too short
    mu is too short over 9 years
    @FloatingRock: Do you have a reference for the deprecation? Both methods have been around for a long time and the key? docs even use has_key? in their example code.
  • FloatingRock
    FloatingRock over 9 years
    @muistooshort my bad, that was Python :(
  • Cesar
    Cesar almost 9 years
    Making a pie is actually complicated
  • Bengala
    Bengala about 8 years
    Better, 3 chars shorter, simpler.
  • stephen.hanson
    stephen.hanson over 7 years
    In Rails 5, the params object is no longer a hash, and I don't see the key? method. edgeapi.rubyonrails.org/classes/ActionController/…
  • mu is too short
    mu is too short over 7 years
    @steve.hanson But if you check the source you'll see that key? is delegated to the contained @parameters instance variable so it still has a key? method. Unfortunately reading the source is often a part of dealing with Rails. I don't have a Rails5 setup handy to check though.
  • stephen.hanson
    stephen.hanson over 7 years
    @muistooshort Oh, nice. I'm still a little hesitant to use methods that aren't part of the documented API, but I'm sure that's safe enough. I've been calling params.to_h.key? for now.
  • mu is too short
    mu is too short over 7 years
    @steve.hanson Um, this is Rails, the "documented API" barely scratches the surface of how things work. You kinda' have to go beyond what's documented if you want to get anything useful done.
  • StCleezy
    StCleezy over 7 years
    Careful using present? with booleans (undefined method `present' for true:TrueClass). The accepted answer with has_key? works for all types.
  • Sean
    Sean almost 7 years
    I like how clean this is. I am new to Ruby though. Any pitfalls or missed edge cases I should know of?
  • Alireza Rahmani khalili
    Alireza Rahmani khalili almost 7 years
    why you do not use unless
  • Mario Pérez Alarcón
    Mario Pérez Alarcón almost 7 years
    you could do params.fetch(:foo, 'default value') too
  • James
    James over 6 years
    To be clear this doesn't work in some cases as e.g. false.present? => false So won't work when e.g. passing parameters via json body as can pass booleans.
  • ltdev
    ltdev over 6 years
    How can I check if params has a key set? I want to use in a method like this def foo(params) return if no params set; do_something; end
  • Jerome
    Jerome over 6 years
    if you are using this logic in a view, present will fail as the parameter array is already being invoked and failing if nil. has_keyinstead gives you what you are looking for.
  • Samet Gunaydin
    Samet Gunaydin almost 5 years
    Rubocop (Ruby linter) warns: C: [Corrected] Style/PreferredHashMethods: Use Hash#key? instead of Hash#has_key?.

Related