パラメータがレールに存在するかどうかをテストする方法


179

Ruby on RailsでIFステートメントを使用して、リクエストパラメータが設定されているかどうかをテストしています。両方のパラメーターが設定されているかどうかに関係なく、ifブロックがトリガーされる次の最初の部分。params [:one]とparams [:two]の両方が設定されている場合に、このパーツのみをトリガーするにはどうすればよいですか?

if (defined? params[:one]) && (defined? params[:two])
 ... do something ...
elsif (defined? params[:one])
 ... do something ...
end

10
@Nakilon:それparamsがRailsコントローラーメソッド(たまたまHashWithIndifferentAccessを返す)であるとすると、それはRailsに関するものです。
muが短すぎる

回答:


348

あなたが欲しいhas_key?

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

チェックif(params[:one])するだけで「there but nil」と「there but false」の値にだまされ、存在を尋ねられます。あなたは区別する必要があるかもしれません:

  • まったくありません。
  • ありますがnil
  • ありますがfalse
  • 空の文字列があります。

同じように。あなたの正確な状況の詳細なしに言うのは難しい。


3
@sawa nilパラメータを渡すことはできません。パラメータが存在する場合、空の文字列になります。
Jacob Relkin

5
@Jacob:params何が入っているかをチェックしているところにたどり着く前に、前処理されていないという保証はありません。したがって、チェックする可能性のある特別なケースの私のリスト。あなたが私見を意味するものを正確に言うのが最善です。
muが短すぎる

1
@muistooshort私の悪いことに、それはPythonでした:(
FloatingRock

2
Rails 5では、paramsオブジェクトはハッシュではなくなり、key?メソッドは表示されません。edgeapi.rubyonrails.org/classes/ActionController/...
stephen.hanson

1
@muistooshortああ、いいね。ドキュメント化されたAPIの一部ではないメソッドを使用することにはまだ少し躊躇していますが、それでも十分安全です。私は今呼びかけparams.to_h.key?ています。
stephen.hanson

86

私はのファンです

params[:one].present?

params[sym]フォームが保持されるので、読みやすくなります。


1
より良い、3文字短く、簡単。
ベンガラ2016年

これが最も有効な応答です。
jacktrade

4
プレゼントを慎重に使用しますか?ブール値(true:TrueClassの未定義メソッド「present」)。has_keyで受け入れられた答えは?すべてのタイプで機能します。
StCleezy

2
明確にするために、たとえばfalse.presentのようにこれが機能しない場合がありますか?=> falseたとえば、ブール値を渡すことができるようにjson本体を介してパラメーターを渡す場合は機能しません。
James

1
このロジックをビューで使用している場合、パラメータ配列がすでに呼び出されているためpresentは失敗し、nilの場合は失敗します。has_key代わりに、あなたが探しているものを提供します。
ジェローム

22

空白を使用しますか?http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

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

空またはnilの場合はtrueを返します

また、ブール値をテストしている場合は機能しません。

>> false.blank?
=> true

その場合、あなたは使うことができます

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

3
またはpresent?の逆を返しますblank?。したがってunlessif必要に応じて、それをに変えることができます。
2014

@Inklingは機能しますが、インラインunlessでも問題ありません。しかし、ええ、私は次の方ifが好きですpresent?
オーランド14

18

次のように簡潔に書くことができます:

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

1
私はこれがいかにきれいかが好きです。Rubyは初めてです。私が知っておくべき落とし穴や見逃されたエッジのケースはありますか?
ショーン

10

パイのようにシンプル:

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

3
これは、パラメーターが存在するかどうかはチェックしませんが、実際にはnilに設定されています。
Daemin

@Daeminただし、実際には、リクエストヘッダーでパラメーターをnilに設定することはできません。nilまたは文字列です。
Jacob Relkin、2011

はい、しかし他の人々が述べたように、それは何か他のもの、プラグイン、gem、またはあなた自身のコードによって変更されるかもしれません、あるいは単に奇妙な理由で解析に失敗するかもしれません。
Daemin、2011

4
パイを作ることは実際には複雑です
Cesar

なぜあなたが使用しないのですか
Alireza Rahmani Khalili 2017年

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

5

パラメータにデフォルト値を提供する非常に簡単な方法: params[:foo] ||= 'default value'


2
あなたが行うことができparams.fetch(:foo, 'default value')、あまりにも
マリオ・ペレス

5

RubyInRailsクラスでこれを読んだだけです http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

blank?と同等のメソッドを使用できますparams[:one].nil? || params[:one].empty?

(例えば)

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

完璧、私が使っていたparams[:one].nil? || params[:one].empty?
GOXR3PLUS

キーが正しいメソッドです。メソッドはこのパラメーターがすでに存在すると想定しているため、nilでnilを検証しています。
ポールブルナッシュ

3

次のこともできます。

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

1つまたは2つ以上のパラメーターをチェックする場合は、上記のソリューションを使用する傾向があります。

.values_atは、未定義のparamキーの代わりにnilの配列を返します。つまり:

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

以下を返します:

[3,nil,5] 

.includes?(nil)は、配列にnil値がないかどうかを確認します。配列にnilが含まれている場合はtrueを返します。

場合によっては、paramsにfalse値の空の文字列が含まれていないことを確認することもできます。

これらの値を処理するには、unlessステートメントの上に次のコードを追加します。

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

まとめると、次のようになります。

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

delete_ifはハッシュ/パラメータを変更するため、注意して使用することに注意してください。

上記の解決策は明らかに設定に少し手間がかかりますが、1つまたは2つ以上のパラメーターをチェックする場合は価値があります。


3

前回の回答に加えて:has_key?has_value?持っている短い代替案の形でkey?とをvalue?。Rubyチーム、より短い代替案の使用も推奨していますが、読みやすさのために、これらのメソッドのより長いバージョンを好む人もいます。

したがって、あなたの場合、それは次のようなものになります

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

NB!.key?キーが存在するかどうかを確認し、可能な値はすべて無視します。例:

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

2

これが私がすることです、

before_action :validate_presence

そして次の方法:

    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

1

同じ問題のためにこれをつなぎ合わせただけです:

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

1行目は、<=サブセットを使用して、ターゲットキーがparamsのキーに存在するかどうかを確認しますか?オペレーター。Enumerable.all?デフォルトのブロックなしでは、いずれかの値がnilまたはfalseの場合はfalseを返します。


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

params [:two] .emptyを使用して、パラメーターが空かどうかを確認することもできます


1
これは両方のパラメータが定義されている場合をカバーしています。それらの1つがfalseと評価されるケースは対象外です。
EmFi 2011

0

私は遅くしようとしますが、遠くからの答え:

(任意の)ハッシュの値が設定されているかどうかを知りたい場合は、その観点に応じて、上記のすべてがtrueと答えます。

あなたは(GET / POST ...)のparamsをテストしたい場合は、あなたがの値であることを期待するものに、より特別なものを使用する必要がありますparams[:one]のようなもの、

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

設定されていないかのようにパラメーター(GET / POST)を無視し、期待どおりに収まらない場合

ただif params[:one] 、それは通常のように使用するものに次のステップであるためではnilなし/真の検出がハッキングのためのあなたのページを開くには、1つのステップでは、あるselect ... where params[:one] ...本がアクティブまたは内またはフレームワークの後、意図されているかどうか、。

答えまたは単なるヒント

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.