如何在Rails中实现动态的自定义错误页面?
例如,使用您的application.html.erb布局的自定义404错误页面以及页面中的一些动态字段。
另外,如何从本地机器测试?
答案 0 :(得分:13)
我查看了Google上有关如何执行此操作的一些博客文章,遗憾的是,大多数人似乎依赖于污染您的ApplicationController。
我所做的是使用404消息创建模板,然后使用该模板从rake任务更新public / 404.html文件:
# Rake file to generate static 404 page
file "public/404.html" => ["app/views/layouts/application.html.erb"] do |t|
print "Updating 404 page\n"
`curl --silent http://locahost/content/error404 -o public/404.html`
end
现在每当我更新我的全局布局时,404页面都会自动更新。
答案 1 :(得分:9)
只需将以下内容添加到ApplicationController:
rescue_from ActiveRecord::RecordNotFound, :with => :render_record_not_found
# Catch record not found for Active Record
def render_record_not_found
render :template => "shared/catchmissingpage", :layout => false, :status => 404
end
# Catches any missing methods and calls the general render_missing_page method
def method_missing(*args)
render_missing_page # calls my common 404 rendering method
end
# General method to render a 404
def render_missing_page
render :template => "shared/catchmissingpage", :layout => false, :status => 404
end
您可以自定义渲染调用(使用模板,使用布局等)并以这种方式捕获错误。现在它为你捕获了缺少的方法和record_not_found,但也许在某些情况下你想要显示500错误页面,这样你就可以继续使用这种方法并使它适合你。
对于从本地计算机进行测试,它就是这样的。如果您只希望它在生产模式下工作,请添加
if ENV['RAILS_ENV'] == 'production'
你没事。
答案 2 :(得分:6)
检查Henrik Nyh's post。其他人也可以通过谷歌找到。
背后的想法:Rails似乎为404错误呈现public/404.html
。
ActionController::Rescue
定义了rescue_action_in_public
来调用render_optional_error_file
。
答案 3 :(得分:3)
如果您决定创建动态404(或其他状态代码)页面,请务必从/public
中删除相应的html文件(如果存在)
答案 4 :(得分:1)
在测试方面,一个非常好的方法(至少用于开发目的)是使用Passenger并将rails环境设置为生产(或在站点配置中注释掉“RailsEnv development”)。至少这种方式你可以模仿它在生产中的运作方式。
但是,为了完成这项工作,我有各种各样的设置文件,这些文件在启动时被解析并根据环境被选中。其中一个设置是是否显示错误页面(AppSettings.show_page_errors?)。然后在我的应用程序控制器中,我有
if !AppSettings.show_page_errors?
alias_method :rescue_action_locally, :rescue_action_in_public
end
因此,它通常设置为默认设置,但有时我真的需要查看到底发生了什么,所以我可以在生产时将其关闭。
另一步是使用自定义页面。在我的情况下,我有基于错误的模板,还包括提交到谷歌表单的表单(因为我的服务器可能被破坏)。为此,请在应用程序控制器中添加(并根据需要进行更改):
def render_optional_error_file(status_code)
status = interpret_status(status_code)
render :template => "/errors/#{status.to_s[0,3]}.html.haml", :status => status, :layout => 'application.html.haml' if [404, 422, 500].include?(status)
render :template => "/errors/unknown.html.haml", :status => status, :layout => 'application.html.haml' unless [404, 422, 500].include?(status)
end
这将使用模板呈现状态代码404,422和500,否则使用未知。如果您需要处理其他人,只需更新此方法并添加模板即可。