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

Ave*_*ery 27 error-handling ruby-on-rails asset-pipeline ruby-on-rails-4

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

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

Dou*_*ell 44

对于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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 编辑路由配置,config/routes.rb将错误页面定向到错误控制器

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

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

  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
    
    Run Code Online (Sandbox Code Playgroud)

    我的偏好是设置状态消息 flash.alert

  4. 自己创建页面.我用的.erbapp/views/errors/500.html.erb

    <p>Our apology.  Your request caused an error.</p>
    <%= render 'product_description' %>
    
    Run Code Online (Sandbox Code Playgroud)

    所以你看到你可以呈现局部.页面呈现所有布局样板app/views/layouts/application.html.erb或来自您已配置的任何其他布局样板.这包括<div id='alert'><%= alert %></div>显示来自闪存的状态消息.

  5. 通过添加测试文件与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
    
    Run Code Online (Sandbox Code Playgroud)

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


Ric*_*eck 5

我们为你做了一个宝石:exception_handler.

还有一个伟大的教程在这里.

我也写了一个广泛的答案关于这个问题在这里.

中间件

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

调节器

# 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
Run Code Online (Sandbox Code Playgroud)

视图

# app/views/exception/show.html.erb
<h1>404 error</h1>
Run Code Online (Sandbox Code Playgroud)

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

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

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