Перехват исключений в вызове рендеринга от помощника rails

Это для приложения rails 4.0.2 под управлением ruby ​​2.0.0-p353.

У меня есть помощник, который имеет следующий метод

def render_feed_row(activity_item)
  begin
    if activity_item.type == "comment"
      render "newsfeed/comment", :item => activity_item
    elsif activity_item.type == "post"
      render "newsfeed/post", :item => activity_item
    else
      raise NameError
    end
  rescue NameError => e # note: NoMethodError is a subclass of NameError
    render "newsfeed/other", :item => activity_item
  end
end

Но если NoMethodError поднят в newsfeed/post частичный, он не пойман в этом помощнике. Это почему? Не рендерится newsfeed/otherНа самом деле это вызывает исключение.

2 ответа

Решение

Я только что проверил с упрощенной версией вашего кода, и она работала правильно.

def render_feed_row
  raise NoMethodError
rescue NameError
  puts "kaboom"
end

render_feed_row
# => kaboom

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

Вот более чистая версия вашего метода

def render_feed_row(activity_item)
  case (type = activity_item.type)
  when "comment", "post"
    render "newsfeed/#{type}", item: activity_item
  else
    render "newsfeed/other", item: activity_item
  end
end

Или более краткая версия

def render_feed_row(activity_item)
  name = case activity_item.type
  when "comment", "post"
    activity_item.type
  else
    "other"
  end
  render "newsfeed/#{name}", item: activity_item
end

Использование исключений для потока управления происходит медленно. Почему не просто

def render_feed_row(activity_item)
  partial = ['comment', 'post'].include?(activity_item.type) ? 
                                                    activity_item.type : 'other'

  render "newsfeed/#{partial}", :item => activity_item
end
Другие вопросы по тегам