Raylarda parametrelerin olup olmadığını test etme


179

İstek parametreleri ayarlanıp ayarlanmadığını denemek ve test etmek için Ruby on Rails bir IF deyimi kullanıyorum. Her iki parametrenin ayarlanıp ayarlanmamasına bakılmaksızın, blok tetiklenirse aşağıdakilerin ilk kısmı. Bu parçayı YALNIZCA hem param [: one] hem de params [: two] ayarlanmışsa nasıl tetikleyebilirim?

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

10
@Nakilon: Bunun paramsbir Rails denetleyici yöntemi (HashWithIndifferentAccess döndüren) olduğu göz önüne alındığında, Rails ile ilgilidir.
mu çok kısa

Yanıtlar:


348

İstediğiniz has_key?:

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

Sadece kontrol etmek if(params[:one])bir "orada ama sıfır" ve "orada ama yanlış" değeri tarafından aldanacak ve varoluş hakkında soruyorsun. Farklılaştırmanız gerekebilir:

  • Orada yok.
  • Orada ama nil.
  • Orada ama false.
  • Orada boş bir dize var.

de. Kesin durumunuz hakkında daha fazla ayrıntı olmadan söylemek zor.


3
@sawa Bir nilparametre iletmek mümkün değildir . Parametre mevcutsa, boş bir dize olacaktır.
Jacob Relkin

5
@Jacob: İçinde paramsne olduğunu kontrol ettiğimiz yere varmadan önce önceden işlenmemiş bir garanti yok . Bu yüzden kontrol etmek için olası özel durumlar listem. Tam olarak ne demek istediğini söylemek en iyisi IMHO.
mu çok kısa

1
@muistooshort benim kötü, o Python oldu :(
FloatingRock

2
Rails 5'te, params nesnesi artık bir karma değildir ve key?yöntemi görmüyorum . edgeapi.rubyonrails.org/classes/ActionController/…
stephen.hanson

1
@muistooshort Oh, güzel. Dokümante edilmiş API'nın bir parçası olmayan yöntemleri kullanmak için hala biraz tereddüt ediyorum, ancak bunun yeterince güvenli olduğundan eminim. params.to_h.key?Şimdilik aradım .
stephen.hanson

86

fanıyım

params[:one].present?

params[sym]Formu sakladığı için okunması daha kolay.


1
Daha iyi, 3 karakter daha kısa, daha basit.
Bengala

bu en geçerli yanıt olmalı!
jacktrade

4
Hediyeyi kullanırken dikkatli misiniz? booleans ile (true için undefined yöntemi mevcut: TrueClass). Has_key ile kabul edilen cevap? her tür için çalışır.
StCleezy

2
Açık olmak gerekirse, bu bazı durumlarda false.present olarak çalışmaz mı? => false Öyleyse, parametreleri boole'lardan geçebileceği gibi json gövdesi üzerinden geçirirken çalışmaz.
James

1
bir görünümde bu mantığı kullanıyorsanız, parametre dizisi zaten çağrıldığından ve nil ise başarısız olduğundan present başarısız olur. has_keybunun yerine size aradığınızı verir.
Jerome

22

boşluk kullan? http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

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

boş veya sıfır olursa doğru dönecektir

ayrıca ... eğer boole değerlerini test ediyorsanız çalışmaz.

>> false.blank?
=> true

bu durumda kullanabilirsiniz

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

3
Veya present?bunun tersini döndürür blank?. Yani bunu istersen unlessbir haline dönüştürebilirsin if.
Inkling

@Bu işe yarıyor ama inline unlessiyi. Ama evet, daha çok seviyorum ifilepresent?
Orlando

18

Aşağıdaki gibi daha özlü bir şekilde yazabilirsiniz:

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
Bunun ne kadar temiz olduğunu seviyorum. Yine de Ruby için yeniyim. Bilmem gereken herhangi bir tuzak ya da kaçırılmış kenar vakası var mı?
Sean

10

Pasta kadar basit:

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
Bu, parametrenin orada olup olmadığını kontrol etmez, ancak aslında nil olarak ayarlanır.
Daemin

@Daemin Gerçekte, bir parametre bir istek başlığında nil olarak ayarlanamaz. Nil ya da bir dize.
Jacob Relkin

Evet ama diğer insanların belirttiği gibi, başka bir şey, bir eklenti, mücevher veya kendi kodunuz tarafından değiştirilebilir veya sadece tuhaf bir nedenden dolayı ayrıştırılamaz.
Daemin

4
Bir pasta yapmak aslında karmaşık
Cesar

neden kullanmadıkça kullanmıyorsunuz
Alireza Rahmani Khalili

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

5

Parametrelerinize varsayılan değerler sağlamanın çok basit bir yolu: params[:foo] ||= 'default value'


2
Yapabileceğin params.fetch(:foo, 'default value')çok
Mario Perez

5

Bunu sadece RubyInRails sınıflarında okudum http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

blank?eşdeğer bir yöntem kullanabilirsinizparams[:one].nil? || params[:one].empty?

(Örneğin)

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

Mükemmel, kullanıyordumparams[:one].nil? || params[:one].empty?
GOXR3PLUS

anahtar doğru yöntemdir, yönteminiz bu parametrenin zaten var olduğunu varsaydı, bu yüzden nil üzerinde çalışabilir ancak en iyi yöntem değil nil doğrulamaktasınız.
Paul Brunache

3

Ayrıca aşağıdakileri de yapabilirsiniz:

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

Bir veya iki parametreden daha fazlasını kontrol etmek istediğimde yukarıdaki çözümü kullanma eğilimindeyim.

.values_at, herhangi bir tanımsız param anahtarının yerine nil ile dizi ve diziyi döndürür. yani:

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

aşağıdakileri döndürür:

[3,nil,5] 

.includes? (nil) sonra diziyi herhangi bir nil değeri olup olmadığını denetler. Dizi nil içeren true döndürecektir.

Bazı durumlarda, parametrelerin false değerinde dize içermediğini ve boş dize olmadığını da kontrol etmek isteyebilirsiniz.

Unless ifadesinin üstüne aşağıdaki kodu ekleyerek bu değerleri işleyebilirsiniz.

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

hep birlikte şöyle görünecektir:

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

Delete_if öğesinin karma / parametrelerinizi değiştireceğini unutmayın, bu nedenle dikkatli kullanın.

Yukarıdaki çözüm, kurulumu biraz daha fazla zaman alır, ancak sadece bir veya iki parametrenin ardından kontrol ediyorsanız buna değer.


3

Önceki cevaplara ek olarak: has_key?ve has_value?sahip daha kısa alternatifler şeklinde key?ve value?. Ruby ekibi ayrıca daha kısa alternatifler kullanmanızı önerir , ancak okunabilirlik için bazıları hala bu yöntemlerin daha uzun sürümlerini tercih edebilir.

Bu nedenle sizin durumunuzda

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

NB! .key?sadece anahtarın var olup olmadığını kontrol eder ve mümkün olan her değeri yok sayar. Örneğin:

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

İşte yaptığım şey,

before_action :validate_presence

ve ardından aşağıdaki yöntemler:

    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

Aynı sorun için bunu bir araya getirdik:

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

ilk satır, hedef anahtarlarımızın parametrelerin anahtarlarında <= alt küme? Şebeke. Enumerable.all? herhangi bir değer nil veya false ise, varsayılan başına blok olmadan false değerini döndürür.


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

Parametrelerin boş olup olmadığını params [: two] kullanarak da kontrol edebilirsiniz.


1
Bu, her iki parametrenin de tanımlandığı durumu kapsar. Bunlardan birinin yanlış olarak değerlendirildiği durumu kapsamaz.
EmFi

0

Geç kaldım, ama uzak görüşten cevap:

Bir (herhangi bir) karedeki değerlerin ayarlanıp ayarlanmadığını bilmek istiyorsanız, yukarıdakilerin tümü, bakış açılarına bağlı olarak doğru yanıtlar.

(GET / POST ..) parametrelerinizi test etmek istiyorsanız, değer olmasını beklediğiniz şeye daha özel bir params[:one]şey,

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

Parametreyi (GET / POST) ayarlanmadığı gibi yok sayılıyor, beklendiği gibi uymuyorlarsa

Sadece bir if params[:one] , genellikle gibi kullanım şeye sonraki adım olduğundan ile veya nil olmadan doğru / algılama hack için sayfa açmak için bir adım olduğunu select ... where params[:one] ...bu aktif veya içinde veya bir çerçeve sonra amaçlanan olup olmadığını.

bir cevap ya da sadece bir ipucu

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.