How to test if parameters exist in rails

Ruby on-RailsRuby

Ruby on-Rails Problem Overview


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

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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 - Ruby on-Rails

I am a fan of

params[:one].present?

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

Solution 3 - Ruby on-Rails

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 - Ruby on-Rails

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 - Ruby on-Rails

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

Solution 6 - Ruby on-Rails

if params[:one] && params[:two]
 ... do something ...
elsif params[:one]
 ... do something ...
end

Solution 7 - Ruby on-Rails

A very simple way to provide default values to your params: params[:foo] ||= 'default value'

Solution 8 - Ruby on-Rails

I just read this on RubyInRails classes http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

you can use blank? method which is equivalent to params[:one].nil? || params[:one].empty?

(e.g)

if params[:one].blank? 
  # do something if not exist
else
  # do something if exist
end

Solution 9 - Ruby on-Rails

You can also do the following:

unless params.values_at(:one, :two, :three, :four).includes?(nil)
 ... excute code ..
end 

I tend to use the above solution when I want to check to more then one or two params.

.values_at returns and array with nil in the place of any undefined param key. i.e:

some_hash = {x:3, y:5}
some_hash.values_at(:x, :random, :y}

will return the following:

[3,nil,5] 

.includes?(nil) then checks the array for any nil values. It will return true is the array includes nil.

In some cases you may also want to check that params do not contain and empty string on false value.

You can handle those values by adding the following code above the unless statement.

params.delete_if{|key,value| value.blank?}

all together it would look like this:

 params.delete_if{|key,value| value.blank?}
 unless params.values_at(:one, :two, :three, :four).includes?(nil)
   ... excute code ..
  end

It is important to note that delete_if will modify your hash/params, so use with caution.

The above solution clearly takes a bit more work to set up but is worth it if you are checking more then just one or two params.

Solution 10 - Ruby on-Rails

In addition to previous answers: has_key? and has_value? have shorter alternatives in form of key? and value?. Ruby team also suggests using shorter alternatives, but for readability some might still prefer longer versions of these methods.

Therefore in your case it would be something like

if params.key?(:one) && params.key?(:two)
  ... do something ...
elsif params.key?(:one)
  ... do something ...
end

NB! .key? will just check if the key exists and ignores the whatever possible value. For ex:

2.3.3 :016 > a = {first: 1, second: nil, third: ''}
  => {:first=>1, :second=>nil, :third=>""}
2.3.3 :017 > puts "#{a.key?(:first)}, #{a.key?(:second)}, #{a.key?(:third), #{a.key?(:fourth)}}"
true, true, true, false

Solution 11 - Ruby on-Rails

Just pieced this together for the same problem:

before_filter :validate_params

private

def validate_params
  return head :bad_request unless params_present?
end

def params_present?  
  Set.new(%w(one two three)) <= (Set.new(params.keys)) &&
  params.values.all?
end

the first line checks if our target keys are present in the params' keys using the <= subset? operator. Enumerable.all? without block per default returns false if any value is nil or false.

Solution 12 - Ruby on-Rails

Here's what I do,

before_action :validate_presence

and then following methods:

    def check_presence
  params[:param1].present? && params[:param2].present?
 end
 
 def validate_presence
  if !check_presence
    render json:  {
                      error:  {
                                message: "Bad Request, parameters missing.",
                                status: 500
                              }
                    }
  end
 end

Solution 13 - Ruby on-Rails

If you want to be able to return an error based on the specific missing parameter without having to switch through all of them:

required_params = [:one, :two, :three]
required_params.each do |param|
  if params[param].blank?
    render json: { errors: "Missing parameter #{param.to_s}." }, :status => :bad_request 
    return
  end
end

Solution 14 - Ruby on-Rails

if params[:one] && param[:two]
  ... excute code ..
end

You can also check if the parameters are empty by using params[:two].empty

Solution 15 - Ruby on-Rails

I try a late, but from far sight answer:

If you want to know if values in a (any) hash are set, all above answers a true, depending of their point of view.

If you want to test your (GET/POST..) params, you should use something more special to what you expect to be the value of params[:one], something like

if params[:one]~=/   / and  params[:two]~=/[a-z]xy/

ignoring parameter (GET/POST) as if they where not set, if they dont fit like expected

just a if params[:one] with or without nil/true detection is one step to open your page for hacking, because, it is typically the next step to use something like select ... where params[:one] ..., if this is intended or not, active or within or after a framework.

an answer or just a hint

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDarrenView Question on Stackoverflow
Solution 1 - Ruby on-Railsmu is too shortView Answer on Stackoverflow
Solution 2 - Ruby on-RailsnetricateView Answer on Stackoverflow
Solution 3 - Ruby on-RailsOrlandoView Answer on Stackoverflow
Solution 4 - Ruby on-RailsZack XuView Answer on Stackoverflow
Solution 5 - Ruby on-RailsJacob RelkinView Answer on Stackoverflow
Solution 6 - Ruby on-Railsfl00rView Answer on Stackoverflow
Solution 7 - Ruby on-RailschrpesView Answer on Stackoverflow
Solution 8 - Ruby on-RailsBasil MarianoView Answer on Stackoverflow
Solution 9 - Ruby on-RailsGreg LView Answer on Stackoverflow
Solution 10 - Ruby on-RailsAndresView Answer on Stackoverflow
Solution 11 - Ruby on-RailsokthatsneatView Answer on Stackoverflow
Solution 12 - Ruby on-RailsParth ModiView Answer on Stackoverflow
Solution 13 - Ruby on-RailsricksView Answer on Stackoverflow
Solution 14 - Ruby on-RailsJason YostView Answer on Stackoverflow
Solution 15 - Ruby on-RailshalfbitView Answer on Stackoverflow