【问题标题】:Rails: How do I create a custom 404 error page that uses the asset pipeline?Rails:如何创建使用资产管道的自定义 404 错误页面?
【发布时间】:2014-08-05 19:30:13
【问题描述】:

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

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

【问题讨论】:

  • 我认为你的第二个参考有你想要的。 但 Rails 4 几乎没有,你确定第二个参考在 rails 4 上不起作用吗?你已经做了什么?
  • 我也有同样的问题,但因为需要多语言。

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


【解决方案1】:

我们已经为您制作了一个宝石: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

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

【讨论】:

  • class ExceptionController &lt; ApplicationController 否则报错
  • 与 rails 版本无关。这是公约。控制器名为NameController,然后您将文件命名为name_controller.rb。 Rails 正在寻找NameController。如果你只调用它 class Name 它会抛出一个 Unable to autoload constant NameController (因为他期望 NameController 但找不到它)
【解决方案2】:

对于 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 提示我独立测试这些请求,并查看它们是否完成并返回正确的内容。

以下是对这三个参考资料所教内容的简要描述:

  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 页面请求路由到 errors 控制器的 show 操作,参数 code 具有状态代码的值。

  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

    <p>Our apology.  Your request caused an error.</p>
    <%= render 'product_description' %>
    

    所以你看到你可以渲染一个部分。该页面使用来自app/views/layouts/application.html.erb 的所有布局样板或您已配置的任何其他布局样板呈现。这包括显示来自闪存的状态消息的&lt;div id='alert'&gt;&lt;%= alert %&gt;&lt;/div&gt;

  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
    

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

【讨论】:

  • 资产管道解决方案只有一个问题。每个 html 文件都以摘要为后缀,因此很难从 Dispatcher::PublicExceptions 中找到。我建议人们尝试这里提到的那个。
猜你喜欢
  • 2015-10-07
  • 2015-07-11
  • 1970-01-01
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多