рельсы если object.nil? тогда магия во взглядах? - PullRequest
32 голосов
/ 07 февраля 2009

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

У меня есть объекты, которые я должен проверить на ноль в своих представлениях, чтобы не разыменовывать ноль:

<%= if tax_payment.user; tax_payment.user.name; end %>

Или я мог бы сделать этот вариант:

<%= tax_payment.user ? tax_payment.user.name : '' %>

Так что это нормально ... для большинства языков. Но я чувствую, что должно быть немного блестящего рубина или рельса, которого я все еще скучаю, если это лучшее, что я могу сделать.

Ответы [ 8 ]

57 голосов
/ 07 февраля 2009

А как же:

<%= tax_payment.user.name if tax_payment.user %>
44 голосов
/ 07 февраля 2009

Вы также можете попробовать новый синтаксис Object.try, простите за каламбур.

Это в блестящем новом Rails 2.3:

tax_payment.try(:user).try(:name)
10 голосов
/ 13 февраля 2009

Сообщество Ruby уделяет невероятное внимание автоматизации этой идиомы. Вот известные мне решения:

Наиболее известным, вероятно, является метод try в Rails. Тем не менее, он получил некоторые критики .

В любом случае я думаю, что решения Бена вполне достаточно.

9 голосов
/ 28 сентября 2011

Я всегда предпочитал такой подход:

модель:

class TaxPayment < ActiveRecord::Base
  belongs_to :user
  delegate :name, :to=>:user, :prefix=>true, :allow_nil=>true
end

вид:

<%= tax_payment.user_name %>

http://apidock.com/rails/Module/delegate

7 голосов
/ 07 февраля 2009

Для более комплексного решения вы можете проверить Ввести нулевой объект Рефакторинг . Основная механика этого рефакторинга заключается в том, что вместо проверки nil в клиентском коде вы вместо этого убедитесь, что провайдер никогда не выдаст nil во-первых, вводить контекстный нулевой объект и возвращать его.

Итак, верните пустую строку, пустой массив, пустой хеш, или специального пустого клиента, или пустого пользователя, или что-то еще вместо nil, и тогда вам никогда не понадобится проверять nil в первую очередь.

Итак, в вашем случае у вас будет что-то вроде

class NullUser < User
    def name
        return ''
    end
end

Тем не менее, в Ruby действительно есть другой, довольно элегантный способ реализации рефакторинга «Ввести нулевой объект»: вам на самом деле не нужно вводить нулевой объект, потому что nil равен уже объект! Таким образом, вы могли бы monkey-patch nil вести себя как NullUser - однако все обычные предупреждения и ловушки, связанные с исправлением обезьян, применяются в этом случае еще сильнее, поскольку nil тихо глотает NoMethodError s или что-то вроде это может полностью испортить ваш опыт отладки и сделать действительно трудным для отслеживания случаев, когда существует nil, которого не должно быть (в отличие от nil, который служит нулевым объектом ).

2 голосов
/ 14 февраля 2009

Еще один вариант, который иногда имеет смысл ...

Если tax_payment.user возвращает nil, печатается nil.to_s (пустая строка), что безопасно. Если есть пользователь, он напечатает имя пользователя.

2 голосов
/ 07 февраля 2009

Я просто делаю

<%= tax_payment.user.name rescue '' %>
0 голосов
/ 28 февраля 2014

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

def print_if_present(var)
    var ? var : ""
end

А затем используйте это так (в представлении):

<%= print_if_present(your_var) %>

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

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