Ответ 1
Как насчет:
<%= tax_payment.user.name if tax_payment.user %>
Это одна из тех вещей, которые, возможно, так просто, что я ее никогда не найду, потому что все это уже знают.
У меня есть объекты, которые я должен проверить для nil в своих представлениях, поэтому я не разыскиваю нуль:
<%= if tax_payment.user; tax_payment.user.name; end %>
Или я мог бы сделать этот вариант:
<%= tax_payment.user ? tax_payment.user.name : '' %>
Так что это нормально... для большинства языков. Но я чувствую, что должен быть какой-то блеск рубинов или рельсов, которых я все еще не вижу, если это лучшее, что я могу сделать.
Как насчет:
<%= tax_payment.user.name if tax_payment.user %>
Вы также можете попробовать новый синтаксис Object.try, pardon pun.
Это в блестящем новом Rails 2.3:
tax_payment.try(:user).try(:name)
Сообщество Ruby привлекло невероятное внимание к автоматизации этой идиомы. Это те решения, о которых я знаю:
Наиболее известным является, вероятно, метод try в Rails. Тем не менее, он получил some критика.
В любом случае, я думаю, что решение Бена вполне достаточно.
Я всегда предпочитал такой подход:
Модель:
class TaxPayment < ActiveRecord::Base
belongs_to :user
delegate :name, :to=>:user, :prefix=>true, :allow_nil=>true
end
Вид:
<%= tax_payment.user_name %>
Для получения более полного решения вы можете проверить Внедрить Репликацию нулевого объекта. Основная механика этого рефакторинга заключается в том, что вместо проверки nil
в клиентском коде вместо этого убедитесь, что поставщик никогда не создает nil
в первую очередь, введя нулевой объект контекста и возвращающий его.
Итак, верните пустую строку, пустой массив, пустой хеш или специальный пустой клиент или пустой пользователь или что-то вместо просто nil
, и вам никогда не понадобится проверять nil
в первую очередь.
Итак, в вашем случае у вас будет что-то вроде
class NullUser < User
def name
return ''
end
end
Тем не менее, в Ruby есть еще один, довольно элегантный способ реализации Refactoring Null Object Refactoring: на самом деле вам не нужно вводить нулевой объект, потому что nil
уже является объектом! Таким образом, вы могли бы обезьян-патч nil
вести себя как NullUser - однако все обычные предупреждения и ловушки в отношении исправления обезьян в этом случае применяются еще сильнее, поскольку nil
молчаливо проглатывает NoMethodError
или что-то в этом роде может полностью испортить ваш отладочный опыт и сделать очень трудным отслеживать случаи, когда есть nil
, который не должен быть там (в отличие от nil
, который служит как Null Object).
Я просто делаю
<%= tax_payment.user.name rescue '' %>
Другой вариант, который иногда имеет смысл...
Если tax_payment.user возвращает nil, выводится nil.to_s (пустая строка), что безвредно. Если есть пользователь, он будет печатать имя пользователя.
Вы можете написать вспомогательный метод, который выглядит следующим образом:
def print_if_present(var)
var ? var : ""
end
И затем используйте его так (в представлении):
<%= print_if_present(your_var) %>
Если var равно нулю, он просто ничего не печатает без привлечения исключения.