How to test if parameters exist in rails
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
Related videos on Youtube
Darren
Updated on November 16, 2021Comments
-
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 about 10 years@Nakilon: Given that
params
is a Rails controller method (that happens to return a HashWithIndifferentAccess), it is about Rails.
-
-
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 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 about 13 yearsWhile this covers the case where both parameters are defined. It does not cover the case where one of them evaluates to false.
-
Dominik Grabiec about 13 yearsThat doesn't check if the parameter is there but actually set to nil.
-
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 about 13 yearsYes 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 almost 10 yearsOr
present?
which returns the opposite ofblank?
. So you could turn thatunless
into anif
if you wanted to. -
Orlando almost 10 years@Inkling that works, but an inline
unless
it's ok. But yeah, I like betterif
withpresent?
-
FloatingRock over 9 years
has_key?
is now deprecated. UseHash.key?
instead -
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 usehas_key?
in their example code. -
FloatingRock over 9 years@muistooshort my bad, that was Python :(
-
Cesar almost 9 yearsMaking a pie is actually complicated
-
Bengala about 8 yearsBetter, 3 chars shorter, simpler.
-
stephen.hanson over 7 yearsIn 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 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 akey?
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 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 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 over 7 yearsCareful using present? with booleans (undefined method `present' for true:TrueClass). The accepted answer with has_key? works for all types.
-
Sean almost 7 yearsI like how clean this is. I am new to Ruby though. Any pitfalls or missed edge cases I should know of?
-
Alireza Rahmani khalili almost 7 yearswhy you do not use unless
-
Mario Pérez Alarcón almost 7 yearsyou could do
params.fetch(:foo, 'default value')
too -
James over 6 yearsTo 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 over 6 yearsHow 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 over 6 yearsif you are using this logic in a view, present will fail as the parameter array is already being invoked and failing if nil.
has_key
instead gives you what you are looking for. -
Samet Gunaydin almost 5 yearsRubocop (Ruby linter) warns:
C: [Corrected] Style/PreferredHashMethods
: UseHash#key?
instead ofHash#has_key?
.