【问题标题】:Rails 3.2 error routing issue. Error ID is conflicting with other object IDRails 3.2 错误路由问题。错误 ID 与其他对象 ID 冲突
【发布时间】:2012-04-05 08:51:18
【问题描述】:

我们刚刚将应用升级到 Rails 3.2.2,现在遇到了处理错误的路由问题。

根据José Valim's blog post,我们添加了以下内容:
config.exceptions_app = self.routes 到 config/application.rb
match "/404", :to => "errors#not_found" 到 config/routes.rb
(以及相应的控制器/视图)。

问题是我们需要ourdomain.com/id 来显示id 产品类别的索引页面。

所以,现在ourdomain.com/404 显示了我们的 404 页面,此时它应该显示我们的类别列表页面,该页面的 id 为 404。

我们如何解决这个问题?
有没有办法让应用程序在 error_ 评估每个错误之前添加 routes
或者,也许以某种方式将config.exceptions_app 设置为引用routes 文件中的命名空间?
或者,我可以创建第二个路由集并设置config.exceptions_app = self.second_set_of_routes吗?

谢谢!

【问题讨论】:

  • 为什么路由设置为/id而不是products/id

标签: ruby-on-rails ruby-on-rails-3 exception-handling routing ruby-on-rails-3.2


【解决方案1】:

到目前为止,我找到了一种解决方案:

# application_controller.rb

def rescue_404
  rescue_action_in_public CustomNotFoundError.new
end

def rescue_action_in_public(exception)
  case exception
    when CustomNotFoundError, ::ActionController::UnknownAction then
      #render_with_layout "shared/error404", 404, "standard"
      render template: "shared/error404", layout: "standard", status: "404"
    else
      @message = exception
      render template: "shared/error", layout: "standard", status: "500"
  end
end

def local_request?
  return false
end

rescue_action_in_public 是 Rails 调用来处理大多数错误的方法。
local_request? 该方法告诉 Rails 如果是本地请求就停止吸吮

# config/routes.rb
match '*path', controller: 'application', action: 'rescue_404' \
  unless ::ActionController::Base.consider_all_requests_local

它只是说它找不到任何其他路由来处理请求(即*path)它应该在应用程序控制器上调用rescue_404 操作(上面的第一个方法)。

编辑

这个版本很适合我! 尝试添加到application.rb

# 404 catch all route
config.after_initialize do |app|
  app.routes.append{ match '*a', to: 'application#render_not_found' } \
    unless config.consider_all_requests_local
end

见:https://github.com/rails/rails/issues/671#issuecomment-1780159

【讨论】:

    【解决方案2】:

    我们遇到了同样的问题——错误代码与根级别资源的 ID 冲突(例如,ourdomain.com/:resource_idourdomain.com/404 之间的冲突)。

    我们修改了 José Valim 的解决方案,添加了仅在处理异常时适用的路由约束:

    # Are we handling an exception?
    class ExceptionAppConstraint
      def self.matches?(request)
        request.env["action_dispatch.exception"].present?
      end
    end
    
    MyApp::Application.routes.draw do
      # These routes are only considered when there is an exception
      constraints(ExceptionAppConstraint) do
        match "/404", :to => "errors#not_found"
        match "/500", :to => "errors#internal_server_error"
    
        # Any other status code
        match '*a', :to => "errors#unknown"
      end
      ...
      # other routes, including 'match "/:resource_id"'
    end
    

    (我们昨晚才偶然发现这个解决方案,所以它没有太多的老化时间。我们使用的是 Rails 3.2.8)

    【讨论】:

      【解决方案3】:

      这条路线似乎是在 show_exceptions 方法中硬编码的 (see source)

      抱歉,除了将上面源代码的第 45 行更改为:

      env["PATH_INFO"] = "/error_#{status}"
      

      (什么是,不用说,根本没有解决方案)。

      问一下也没什么坏处:如果您认为实现自己的错误控制器是一件好事,如此简单且迫切地想要拥有它,那么如果您的路由是您的域,那岂不是更“RESTful”。 com/product/:id?

      【讨论】:

      • 您可以使用初始化程序对其进行修补。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-24
      • 2020-08-11
      • 2020-07-13
      • 2013-05-20
      相关资源
      最近更新 更多