Как проверить, существуют ли параметры в рельсах

133

Я использую инструкцию IF в Ruby on Rails, чтобы попробовать и проверить, установлены ли параметры запроса. Независимо от того, установлены оба параметра, первая часть следующего, если блок запускается. Как я могу заставить эту часть ТОЛЬКО запускаться, если установлены оба параметра [: 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.
Теги:

14 ответов

281
Лучший ответ

Вы хотите has_key?:

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

Просто проверка if(params[:one]) будет обманута значением "there but nil" и "there but false", и вы спрашиваете о существовании. Возможно, вам придется различать:

  • Не существует вообще.
  • Там, но nil.
  • Там, но false.
  • Там есть пустая строка.

. Трудно сказать, не более подробно о вашей конкретной ситуации.

  • 0
    Если параметр равен nil , его там нет.
  • 1
    @ Джейкоб Почему это? мю прав.
Показать ещё 16 комментариев
61

Я - поклонник

params[:one].present?

только потому, что он сохраняет форму params [sym], поэтому ее легче читать.

  • 0
    хорошая точка зрения. Я изменил свое заявление обратно на это.
  • 1
    Лучше, 3 символа короче, проще.
Показать ещё 4 комментария
20

использовать пробел? http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F

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

вернет true, если его пустая или nil

также... это не будет работать, если вы тестируете логические значения.. поскольку

>> false.blank?
=> true

в этом случае вы можете использовать

unless params[:one].to_s.blank? && params[:two].to_s.blank?
  • 3
    Или present? который возвращает противоположность blank? , Таким образом , вы могли бы превратить это unless в if если вы не хотели.
  • 0
    @ Inkling, который работает, но встроенный, unless это не нормально. Но да, мне больше нравится, if с present?
9

Просто как пирог:

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
  • 2
    Это не проверяет, есть ли параметр, но на самом деле установлен на ноль.
  • 0
    @Daemin В действительности, параметр не может быть установлен равным nil в заголовке запроса. Это либо ноль, либо строка.
Показать ещё 3 комментария
8

Вы можете написать его более кратко следующим образом:

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
  • 0
    Мне нравится, как это чисто. Хотя я новичок в Ruby. Какие-нибудь подводные камни или пропущенные крайние случаи, о которых я должен знать?
5

Очень простой способ предоставить значения по умолчанию вашим параметрам: params[:foo] ||= 'default value'

  • 1
    Вы также можете сделать params.fetch(:foo, 'default value')
3

Я просто прочитал это на классах 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
  • 0
    Отлично, я использовал params[:one].nil? || params[:one].empty?
  • 0
    has key - правильный метод, ваш метод предполагал, что этот параметр уже существует, поэтому вы проверяете nil на nil, что может сработать, но не лучший метод.
3
if params[:one] && params[:two]
 ... do something ...
elsif params[:one]
 ... do something ...
end
1

Вот что я делаю,

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
  • 0
    Работает как шарм, спасибо.
1

Вы также можете сделать следующее:

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

Я стараюсь использовать вышеупомянутое решение, когда хочу проверить более одного или двух параметров.

.values_at возвращает и массив с nil вместо любого параметра undefined param key. i.e:

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

вернет следующее:

[3,nil,5] 

.includes? (nil) затем проверяет массив для любых значений nil. Он вернет true, массив включает nil.

В некоторых случаях вам также может потребоваться проверить, что параметры не содержат и пустая строка при ложном значении.

Вы можете обрабатывать эти значения, добавив следующий код выше инструкции except.

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 будет изменять ваши хэш-параметры, поэтому используйте их с осторожностью.

В приведенном выше решении явно требуется немного больше работы для настройки, но стоит того, если вы проверяете более одного или двух параметров.

0

В дополнение к предыдущим ответам: has_key? и has_value? имеют более короткие альтернативы в форме key? и value?. Команда Ruby также предлагает использование более коротких альтернатив, но для readability некоторые из них могут по-прежнему предпочитать более длинные версии этих методов.

Поэтому в вашем случае это будет что-то вроде

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
0

Просто соединить это вместе для одной и той же проблемы:

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

первая строка проверяет, находятся ли наши целевые ключи в ключах params, используя <= subset? оператор. Enumerable.all? без блока по умолчанию возвращает false, если любое значение равно nil или false.

0

Я пробую поздно, но из дальновидного ответа:

Если вы хотите знать, установлены ли значения в (любом) хеше, все выше отвечает на истину, в зависимости от их точки зрения.

Если вы хотите проверить свои параметры (GET/POST..), вы должны использовать что-то более особенное для того, что вы ожидаете от значения params[:one], что-то вроде

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

игнорирование параметра (GET/POST), как если бы они не были установлены, если они не соответствуют ожидаемым

только a if params[:one] с обнаружением nil/true или без него - это один шаг, чтобы открыть вашу страницу для взлома, потому что обычно это следующий шаг, чтобы использовать что-то вроде select ... where params[:one] ..., если это предназначено или нет, внутри или после рамки.

ответ или просто подсказка

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

Вы также можете проверить, пустыми ли параметры, используя params [: two].empty

  • 1
    Хотя это охватывает случай, когда оба параметра определены. Это не распространяется на случай, когда один из них оценивается как ложный.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню