Лучшая альтернатива, чтобы попробовать метод - PullRequest
0 голосов
/ 01 марта 2019

Мне нужен чистый кусок кода, и я думаю, что это выглядит неуклюже.

Есть ли лучший способ сделать это?

User.try(:profile).try(:settings).try(:card).try(:options)

Если я исключу методы try, яполучить ошибку метода nil.

Есть ли другой фрагмент кода, который делает что-то вроде:

User.try(:profile,:settings, :card, :options)

Ответы [ 4 ]

0 голосов
/ 01 марта 2019

Я знаю, что это в левом поле, но вы знаете, разнообразие в мышлении.

Я создал (очень крошечный) безжизненный драгоценный камень, который позволяет выполнять код с беспокойством об ошибках.Используя этот гем, код будет выглядеть так:

insouciant(nil) { User.profile.settings.card.options }

с небольшим дополнительным «преимуществом» отлова всех стандартных ошибок, а не только ошибок метода nil.Значение nil возвращается при ошибке.Вы можете заменить его другим значением, если это имеет больше смысла в вашем приложении.

Пропуск параметра полностью вернет сообщение об ошибке в виде строки.

0 голосов
/ 01 марта 2019

В ruby ​​2.3.0 вы можете использовать метод &. вместо try:

User&.profile&.settings&.card&.options

Но вам следует избегать подобных вещей.

Когда вы отправляете сообщения объектамэто может вернуть nil или когда объект не отвечает на это сообщение, эту проблему вы должны решить самостоятельно.Использование try только усугубляет проблему, так же, как и nil -checking. Написать согласованные интерфейсы, которые ведут себя согласованно.

0 голосов
/ 01 марта 2019

Просто для удовольствия

Сверните свои собственные:

# concerns/deep_try.rb

module DeepTry
  def deep_try(*methods)
    methods.reduce(self) { |receiver, method| receiver.try(method) }
  end
end

# user.rb (or anywhere else you want it)
extend DeepTry

Это позволит вам безопасно позвонить по следующему номеру:

User.deep_try(:profile, :settings, :card, :options)

Выможно также использовать на уровне экземпляра:

@user.extend(DeepTry).deep_try(:profile, :settings, :card, :options)
0 голосов
/ 01 марта 2019

Если вы используете версию Ruby более 2.3, вы можете вместо этого использовать безопасный оператор.Например,

User.profile&.settings&.card&.options

Разве это не аккуратно?

...