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

时间:2014-06-16 02:01:43

标签: ruby-on-rails ruby-on-rails-4 error-handling asset-pipeline

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

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

2 个答案:

答案 0 :(得分:41)

对于Rails 4.1我更喜欢this answer, add an asset type;但是我还没试过。在Rails 4.0.8上,这三个引用帮助了我:

  1. Dynamic error pages是问题中的第二个参考。这对我来说很好。

  2. Custom error pages可能已经从第一个引用中获得了支持,反之亦然,但通过添加有关使用Capybara进行测试的一些信息,可以获得额外的帮助。

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

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

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

      # Route exceptions to the application router vs. default
      config.exceptions_app = self.routes
      
    2. 编辑路由配置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控制器的errors操作,并使用具有状态代码值的参数code。< / p>

    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. 上设置状态讯息
    5. 自己创建页面。我使用.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>

    6. 通过添加测试文件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
      

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

答案 1 :(得分:5)

我们为您制作了一个宝石:exception_handler

还有一个很棒的教程here

我还就这个主题写了一个广泛的答案here

<强>中间件

# 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
<h1>404 error</h1>

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

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

如果您发表评论,如果您愿意,我会帮您解决一些问题!