2015-12-21 4 views
3

я имел некоторый код, который выглядел примерно так:Рубите спасательный и лучшей практику синтаксис

foo = SomeActiveRecordModel.where(bar: 10).first.foo rescue '' 

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

foo = 
begin 
    foo = SomeActiveRecordModel.where(bar: 10).first.foo 
rescue NoMethodError 
    '' 
end 

И:

foo = SomeActiveRecordModel.where(bar: 10).first 
foo.present? ? foo.foo : '' 

Какой из этих способов было бы предпочтительнее, или есть альтернативный способ, который является предпочтительным ?

+0

Из любопытства, где вы используете это? Я вижу, что все три ответа объединены, чтобы быть выдающимися. Но если вы используете это в контроллере, возможно, перемещение метода метода 'where' вызовом' scope' или 'class method' в' SomeActiveRecordModel' может быть приятнее. – vee

+0

Это используется в методе класса. Он используется для захвата любых правил, существующих из базы данных, и применения этих правил к sql-запросу. – CarlyL

ответ

5

Обычного правило заключается в том, что исключения должны быть зарезервированы для исключительных обстоятельств, те, которые вы не ожидаете в нормальном потоке управления. Во-первых, они обычно медленнее, чем альтернативы.

Вот что я предпочитаю для сценария:

foo = SomeActiveRecordModel.find_by_bar(10).try(:foo) || '' 
+0

Или даже 'SomeActiveRecordModel.find_by (bar: 10) .try (: foo) || ''' или, возможно, 'SomeActiveRecordModel.find_by (bar: 10) .try (: foo) .to_s' как' foo', по-видимому, является строкой. –

+0

Я видел синтаксис, как это раньше, но это даже не перешло мне в голову, чтобы попробовать. Спасибо за ваш ответ и время, которое вы проводите, описывая его. – CarlyL

3

Отныне ни один из них не будет предпочтительным. Предпочтительный способ был бы:

foo = SomeActiveRecordModel.where(bar: 10).first&.foo || "" 
+4

Я чувствую, что этот новый оператор будет сильно злоупотреблять. :) –

+0

Whoa, whoa, когда это произошло? И почему*? – zetetic

+1

@zetetic: [ruby 2.3] (http://nithinbekal.com/posts/ruby-2-3-features/). Потому что причины. –

9

Обработка исключений для, хорошо, обработка исключительных ситуаций. Ясно, что иногда записи не может быть. Обработка его с помощью ловли NoMethodError - это абсолютно неправильный способ сделать это. Во-первых, он не только поймает «no method foo on nil: NilClass», но и все другие ошибки «без метода», которые могут произойти (опечатка где-то и т. Д.).

Итак, «запись не найдена», являющаяся не исключительной ситуацией, вы должны обрабатывать ее как таковую, с условным определением.

foo = SomeActiveRecordModel.where(bar: 10).first 
return '' unless foo 
foo.bar 
+0

Это имеет большой смысл. Спасибо, что нашли время, чтобы рассказать мне об этом. – CarlyL