如何正确呈现自定义404和500页?

是否有办法告诉Rails呈现您的自定义错误页面(例如,您在ErrorsController编写的错误页面)? 我搜索了很多主题,看起来有点工作的是添加到你的ApplicationController东西

 if Rails.env.production? rescue_from Exception, :with => :render_error rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found rescue_from ActionController::UnknownController, :with => :render_not_found rescue_from ActionController::UnknownAction, :with => :render_not_found end 

然后你按照你想要的方式编写你的方法render_errorrender_not_found 。 在我看来,这似乎是一个非常不优雅的解决方案。 此外,这很糟糕,因为您必须确切知道可能发生的所有错误是什么。 这是一个临时解决方案。

而且,实际上没有简单的方法来拯救ActionController::RoutingError 。 我看到一种方法是添加类似的东西

 get "*not_found", :to => "errors#not_found" 

到你的routes.rb 。 但是如果你想手动提升ActionController::RoutingError呢? 例如,如果非管理员的人试图通过猜测URL来“管理”控制器。 在那些情况下,我更喜欢提高404而不是某种类型的“未经授权的访问”错误,因为这实际上会告诉该人他猜到了URL。 如果你手动提高它,它将尝试渲染500页,我想要一个404。

那么有没有办法告诉Rails:“在所有情况下,你通常会渲染一个404.html500.html ,渲染我的自定义404和500页”? (当然,我从public文件夹中删除了404.html500.html页面。)

不幸的是,没有任何我知道的方法可以被覆盖以提供你想要的东西。 你可以使用aroundfilter。 您的代码看起来像这样:

 class ApplicationController < ActionController::Base around_filter :catch_exceptions protected def catch_exceptions yield rescue => exception if exception.is_a?(ActiveRecord::RecordNotFound) render_page_not_found else render_error end end end 

您可以根据自己的方法处理每个错误。 然后你的#render_page_not_found#render_error方法必须是这样的

 render :template => 'errors/404' 

然后你需要在app/views/errors/404.html.[haml|erb]上有一个文件app/views/errors/404.html.[haml|erb]