Как правильно проверить наличие объектов в Rails / Ruby? - PullRequest
5 голосов
/ 20 января 2011

У меня много моделей и отношений.В связи с этим в представлениях / контроллерах происходит много вызовов, которые выглядят следующим образом:

 @object.something.with_something.value 

Некоторая часть цепочки может оказаться нулевой, что совершенно нормально.Какой правильный / чистый / быстрый способ проверить наличие терминального объекта?

Вызывает ли что-то вроде:

 @object.something.with_something.value if defined? @object.something.with_something.value 

Считается, нормально?

Ответы [ 4 ]

8 голосов
/ 20 января 2011

Собственно, вам нужно использовать оператор && (не defined?), но это может стать очень многословным, очень быстро.

Так что вместо этого:

(@object && @object.something && @object.something.with_something &&
  @object.something.with_something.value)

Вы можете сделать это, когда ActiveSupport присутствует:

@object.try(:something).try(:with_something).try(:value)

Или установите конструктор вызова и используйте его защищенные инструменты оценки:

Ick::Maybe.belongs_to YourClass
maybe(@object) { |obj| obj.something.with_something.value }
3 голосов
/ 20 января 2011

Лучше расположить оставшуюся часть кода, чтобы увидеть эту проблему не более чем для последнего объекта в цепочке.

defined? не будет делать то, что вы хотите.Что-то может быть defined? и nil одновременно.

Когда проблема ограничена последним атрибутом в цепочке ссылок:

@object.something.with_something.value if @object.something.with_something

Я мог бы воспользоватьсяфакты, которые:

nil.to_a => []
nil.to_s => ''
nil.to_f => 0.0
nil.to_i => 0

Итак, если вы знаете, что что-то является либо nil, либо Array, часто вы можете написать лучший код без каких-либо условий вообще, написавчто-то вроде:

something.to_a.each do |e|
  . . .
2 голосов
/ 20 января 2011

what.you.are.doing иногда называют «крушение поезда».Это также описывается как нарушение Закона Деметры.

При этом я думаю, что есть нечто, называемое "andand", которое может помочь с тем, что вы делаете.

0 голосов
/ 20 января 2011

Другой вариант - использовать шаблон Null Object , чтобы убедиться, что ни один из этих объектов не равен nil.Можно утверждать, что если ваш код будет таким образом связывать доступ, то всегда должно быть определено что-то .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...