Rails 4:如何创建使用资产管道的自定义404页面?

有许多解决方案可用于创建自定义error handling页面,但Rails 4几乎没有:

  • 基本Rails 404错误页面
  • Rails中的动态错误页面

鼓励人们修改404.html in /public的标准答案对我不起作用,因为我想使用驻留在资产管道中的CSS主题。 有没有办法让html文件可以访问资产管道中定义的那些样式? 如果没有, 有没有办法创建一个可以访问管道的自定义error handling程序?

对于Rails 4.1我喜欢这个答案,更好地添加资产类型 ; 但是我还没试过。 在Rails 4.0.8上,这三个引用帮助了我:

  1. 动态错误页面是问题中的第二个参考。 这对我来说很好。

  2. 自定义错误页面可能已经从第一个参考文件中抄袭,或者相反,但通过添加有关使用Capybara进行测试的一些信息,可以获得额外的帮助。

  3. 我没有进行Capybara测试,因为我不想改变测试配置; 但是, RSpec-Rails Request Specs让我自己独立测试这些请求并看到它们完成并返回正确的内容。

以下是三个参考文献所教导内容的简要描述:

  1. 将以下设置添加到config/environments/production.rb

     # Route exceptions to the application router vs. default config.exceptions_app = self.routes 
  2. 编辑路由配置config/routes.rb以将错误页面config/routes.rb到错误控制器

      # error pages %w( 404 422 500 503 ).each do |code| get code, :to => "errors#show", :code => code end 

    将使用具有状态代码值的参数code将404,422,500和503页面请求路由到errors控制器的show动作。

  3. 创建控制器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上设置状态消息

  4. 自己创建页面。 我使用.erb这是app/views/errors/500.html.erb

     

    Our apology. Your request caused an error.

    <%= render 'product_description' %>

    所以你看到你可以呈现部分。 该页面使用app/views/layouts/application.html.erb所有布局样板或您已配置的任何其他布局样板进行渲染。 其中包括

    <%= alert %>

    ,它显示来自闪存的状态消息。

  5. 通过添加测试文件spec/requests/errors_request_spec.rb与RSpec进行测试。 以下是该文件的缩写内容,显示了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 

    第一个断言检查闪光警报。 第二个断言检查部分。

我们已经为你做了一个gem: exception_handler

这里还有一个很棒的教程。

我在这里也写了一篇关于这个主题的广泛答案。

中间件

 # config/application.rb config.exceptions_app = ->(env) { ExceptionController.action(:show).call(env) } 

调节器

 # 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 

视图

 # app/views/exception/show.html.erb 

404 error

这是非常简单的版本 - 如果您愿意,我可以解释更多。

基本上,您需要挂钩到config.exceptions_app中间件,它将捕获middleware堆栈中的任何exception(而不是呈现整个环境),允许您将请求发送到您自己的controller#action

如果您发表评论,如果您愿意,我会帮助您更多!