Чистый способ проверки на "нулевую" строку - PullRequest
3 голосов
/ 09 октября 2019

У меня есть сценарий, в котором я специально ищу String со значением "nil". Короче говоря, у меня есть условие, в котором я хочу передать nil, если пользователь выбирает эту опцию в раскрывающемся списке, а не передать "nil", что и передается в параметрах:

Мой выбор:

<select name="parent_id"> 
  <option name="All">All</option>
  <option name="None" value="nil">None</option>
</select>

Мое состояние:

if params[ :parent_id ].present?
  Child.where( parent_id: params[ :parent_id ] ) # I want this to be IS NULL when params[ :parent_id ] == "nil"
end

Как правило, вы должны использовать .nil? или .blank? для String, чтобы проверить значение nil или пустое String. Но "nil".nil? и "nil".blank? равны false, как и должно быть.

Поэтому мне любопытно, есть ли хороший способ проверить, является ли String "nil".

В настоящее время я использую myString == "nil", но это приводит к таким вещам, как ( myString == "nil" ? nil : myString ).

if params[ :parent_id ].present?
  parent_id = params[ :parent_id ] == "nil" ? nil : params[ :parent_id ]
  Child.where( parent_id: parent_id )
end

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

Это довольно редкое явление, я знаю, но это было особенно сложнов Google, поэтому я решил спросить SO.

Мои первоначальные мысли:

  • Добавить метод к String, чтобы вы могли сделать что-то вроде "nil".nil_literal? #=> true.
  • Monkey patch .presence?, так что "nil".presence? возвращает nil вместо "nil".

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Я бы посоветовал изменить выбор на:

  <option name="None" value="">None</option>

Если вы не можете сделать это - я бы воздержался от исправлений обезьян.

Вы можете добавить "nil"проверяя условия:

if params[ :parent_id ].present? && params[ :parent_id != 'nil' 
  Child.where(parent_id: params[:parent_id]))
end

или вы можете отфильтровать params отдельным методом:

def filtered_params
  @filtered_params |= params.tap{|p| p[:parent_id] = nil if p[:parent_id] == 'nil' }
end

и использовать filtered_params вместо params в коде вашего контроллера.

0 голосов
/ 09 октября 2019

Вот как бы я это сделал

class Child 
  belongs_to :parent 

  scope :by_parent, ->(parent_id=nil) { 
    parent_id.to_i == 0 ? without_parent : where(parent_id: parent_id.to_i)
  }
  scope :without_parent, -> { where(parent_id: nil) } 
end 

тогда код вашего контроллера просто

 Child.by_parent(params[:parent_id])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...