обработка нулевых (нулевых) значений в рельсах вложенных отношений 2.3.x - PullRequest
2 голосов
/ 24 июля 2011

Проект, в котором я сейчас работаю, имеет следующие коды в представлении

<%= product.provider.name %>

, приведенный выше код - получить «поставщика» для продукта и отобразить его / ее имя.Но мой вопрос был иногда, что этот код не работает, когда «провайдер» получает ноль.(Я знаю, это немного необычно, но так как я работаю с устаревшей БД, это происходит)

Итак, чтобы проверить проверку на nil, я написал следующий код (в моем ApplicationHelper)

def t(obj, attr)
    obj.nil? ? "" : obj.send(attr.to_sym)
end

Теперь я делаю что-то вроде этого

<%= t(product.provider, "name") %>

Даже если это работает, я столкнулся с другой проблемой, но нашел этот код

<%= product.provider.provider_type.title %>

Проблема здесь в том,в приведенном выше коде «provider» или «provider_type» может быть ноль.

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

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

Или это совершенно неверный путь для обработки нулевых значений во вложенных отношениях

Ваши мысли будут высоко оценены (я бегу по рельсам 2.3.8)

заранее спасибо

ура

Самера

Ответы [ 4 ]

5 голосов
/ 24 июля 2011

Это распространенная проблема.Вы можете проверить это:

Примеры:

# With try
product.provider.try(:name)
product.provider.try(:provider_type).try(:title)

# With andand
product.provider.andand.name
1 голос
/ 25 июля 2011

, поскольку мы можем использовать # try методы или обрабатывать исключения inline, этот метод использования нарушает закон Деметры: Каждая единица должна иметь только ограниченные знания о других единицах: только единицы "тесно "относится к текущей единице.

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

1 голос
/ 24 июля 2011

Вы можете спасти все исключения:

<%= product.provider.provider_type.title rescue nil %>
0 голосов
/ 25 июля 2011

Я решил проблему следующим образом:

class Object
  def unless_nil(default = nil, &block)
    if nil?
      default
    else
      block[self]
    end
  end
end

product.provider.unless_nil(&:name)
product.provider.unless_nil(&:provider_type).unless_nil(&:title)
product.provider.unless_nil("Not specified", &:name)

Также довольно удобно иметь Object#unless_blank, Array#unless_empty, Hash#unless_empty.

Добавлено:

Между тем использование полного блока в некоторых случаях еще удобнее:

some_variable = 
  product.provider.unless_nil do |provider|
    # some complex logic here using provider
  end

Мне нравится больше, чем:

provider = product.provider
some_variable = 
  if provider
    # ...
  end

или использование product.provider везде. Дело вкуса, хотя.

...