从rails帮助程序捕获渲染调用中的异常

时间:2013-12-16 09:02:09

标签: ruby-on-rails ruby ruby-on-rails-4 activeview

这适用于运行ruby 2.0.0-p353的rails 4.0.2应用程序。

我有一个帮手,有以下方法

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 个答案:

答案 0 :(得分:2)

我刚刚检查了您的代码的简化版本,并且它运行正常。

def render_feed_row
  raise NoMethodError
rescue NameError
  puts "kaboom"
end

render_feed_row
# => kaboom

但请注意,以这种方式使用控制流的异常是一种非常糟糕的做法。此外,如果你真的想要使用异常,你应该创建自己的类,而不是使用在Ruby程序中具有特定含义的NoMethodErrorNameError

这是一个更干净的方法版本

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

答案 1 :(得分: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