Ruby-on-rails Rails 4:如何创建使用资产管道的自定义 404 页面?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24235805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails 4: How do I create a custom 404 page that uses the asset pipeline?
提问by Avery
There are many solutions for creating customized error handling pages, but almost none for Rails 4:
创建自定义错误处理页面有很多解决方案,但对于 Rails 4 几乎没有:
The standard answer of encouraging people to modify 404.htmlin /publicdoesn't work for me because I want to use the CSS theme that resides in the asset pipeline. Is there a way that html files can access those styles defined in the asset pipeline?If not, is there a way to create a custom error handler that has access to the pipeline?
标准答案鼓励人们修改404.html在/public我不工作,因为我想用CSS主题驻留在资产管道。有没有办法让 html 文件可以访问资产管道中定义的那些样式?如果没有,有没有办法创建一个可以访问管道的自定义错误处理程序?
回答by Douglas Lovell
For Rails 4.1 I like this answer, add an asset typebetter; however I have not tried it. On Rails 4.0.8, these three references helped me:
对于 Rails 4.1 我喜欢这个答案,更好地添加资产类型;但是我还没有尝试过。在 Rails 4.0.8 上,这三个参考资料帮助了我:
Dynamic error pagesis the second reference in the question. This worked just fine for me.
Custom error pagesmay have cribbed from the first reference, or the other way around, but goes the extra mile by adding some information about testing with Capybara.
I did not do the Capybara testing because I didn't want to change the test configuration; however, RSpec-Rails Request Specsclued me in to test these requests independently and see that they complete and return the correct content.
动态错误页面是问题中的第二个参考。这对我来说很好。
自定义错误页面可能从第一个参考文献中抄袭,或者相反,但通过添加一些有关使用 Capybara 进行测试的信息,更进一步。
我没有做 Capybara 测试,因为我不想改变测试配置;然而,RSpec-Rails 请求规范提示我独立测试这些请求,并查看它们是否完成并返回正确的内容。
What follows is a nutshell description of what is taught by the three references:
以下是对三篇参考文献所教内容的简要描述:
Add the following setting to
config/environments/production.rb# Route exceptions to the application router vs. default config.exceptions_app = self.routesEdit the routing configuration,
config/routes.rbto direct the error pages to an errors controller# error pages %w( 404 422 500 503 ).each do |code| get code, :to => "errors#show", :code => code endwill route the 404, 422, 500, and 503 page requests to the
showaction of theerrorscontroller with a parametercodethat has the value of the status code.Create the controller,
app/controllers/errors_controller.rb. Here is the entire content:class ErrorsController < ApplicationController def show status_code = params[:code] || 500 flash.alert = "Status #{status_code}" render status_code.to_s, status: status_code end endMy preference was to set a status message on
flash.alertCreate the pages themselves. I use
.erbHere isapp/views/errors/500.html.erb<p>Our apology. Your request caused an error.</p> <%= render 'product_description' %>So you see that you can render a partial. The page renders with all of the layout boilerplate from
app/views/layouts/application.html.erbor any other layout boilerplate that you have configured. That includes the<div id='alert'><%= alert %></div>that displays the status message from the flash.Tested with RSpec by adding a test file,
spec/requests/errors_request_spec.rb. Here is abbreviated content of that file that shows a test of the 500 status page:require 'rails_helper' RSpec.describe "errors", :type => :request do it "displays the 500 page" do get "/500" assert_select 'div#alert', 'Status 500' assert_select 'div[itemtype]' end endThe first assertion checks for the flash alert. The second assertion checks for the partial.
将以下设置添加到
config/environments/production.rb# Route exceptions to the application router vs. default config.exceptions_app = self.routes编辑路由配置,
config/routes.rb将错误页面定向到错误控制器# error pages %w( 404 422 500 503 ).each do |code| get code, :to => "errors#show", :code => code end将使用具有状态代码值的参数将404、422、500 和 503 页面请求路由到控制器的
show操作。errorscode创建控制器,
app/controllers/errors_controller.rb。以下是全部内容:class ErrorsController < ApplicationController def show status_code = params[:code] || 500 flash.alert = "Status #{status_code}" render status_code.to_s, status: status_code end end我的偏好是设置状态消息
flash.alert自己创建页面。我用
.erb这里是app/views/errors/500.html.erb<p>Our apology. Your request caused an error.</p> <%= render 'product_description' %>所以你看到你可以渲染部分。该页面使用
app/views/layouts/application.html.erb您配置的所有布局样板或任何其他布局样板呈现。这包括<div id='alert'><%= alert %></div>显示来自闪存的状态消息。通过添加测试文件,使用 RSpec 进行测试
spec/requests/errors_request_spec.rb。以下是该文件的缩写内容,显示了 500 状态页面的测试:require 'rails_helper' RSpec.describe "errors", :type => :request do it "displays the 500 page" do get "/500" assert_select 'div#alert', 'Status 500' assert_select 'div[itemtype]' end end第一个断言检查闪光警报。第二个断言检查部分。
回答by Richard Peck
We've made a gem which does this for you: exception_handler.
我们制作了一个 gem,可以为您执行此操作:exception_handler.
There is also a great tutorial here.
还有一个伟大的教程在这里。
I also wrote an extensive answer on the subject here.
我也写了一个广泛的答案关于这个问题在这里。
Middleware
中间件
# config/application.rb
config.exceptions_app = ->(env) { ExceptionController.action(:show).call(env) }
Controller
控制器
# app/controllers/exception_controller.rb
class ExceptionController < ApplicationController
respond_to :json, :js, :html
before_action :set_status
def show
respond_with @status
end
private
def set_status
def status
@exception = env['action_dispatch.exception']
@status = ActionDispatch::ExceptionWrapper.new(env, @exception).status_code
@response = ActionDispatch::ExceptionWrapper.rescue_responses[@exception.class.name]
end
end
end
View
看法
# app/views/exception/show.html.erb
<h1>404 error</h1>
This is very simple version - I can explain more if you wish.
这是非常简单的版本 - 如果您愿意,我可以解释更多。
Basically, you need to hook into the config.exceptions_appmiddleware, it will capture any exception in the middlewarestack (as opposed to rendering the entire environment), allowing you to send the request to your own controller#action.
基本上,您需要挂钩到config.exceptions_app中间件,它会捕获middleware堆栈中的任何异常(而不是渲染整个环境),从而允许您将请求发送到您自己的controller#action.
If you comment, I'll help you out some more if you want!
如果您发表评论,如果您愿意,我会为您提供更多帮助!

