2013-12-16 5 views
1

Это для приложения 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, это действительно вызывает исключение.

+0

Как ни странно, я поймала 'NoMethodError' при подъеме' NameError' исключение. Пожалуйста, покажите нам вывод 'NoMethodError.superclass' в среде –

+0

Интересно ... Я получаю« NoMethodError in Users :: Profile # transaction_log »из-за« неопределенного метода 'display_name» для nil: NilClass « – Cyrus

+0

Я думаю, что вы должны указать что-то вроде 'rescue NameError, NoMethodError => e'? он позволит поймать 'NoMethodError' в текущем пространстве имен. –

ответ

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 
0

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

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

    render "newsfeed/#{partial}", :item => activity_item 
end