简体   繁体   English

Rails 3.2错误路由问题。错误ID与其他对象ID冲突

[英]Rails 3.2 error routing issue. Error ID is conflicting with other object ID

We just upgraded our app to Rails 3.2.2 and are now having a routing issue for handling errors. 我们刚刚将我们的应用程序升级到Rails 3.2.2,现在遇到了处理错误的路由问题。

Per José Valim's blog post , we added the following: 根据JoséValim的博客文章 ,我们添加了以下内容:
config.exceptions_app = self.routes to config/application.rb config.exceptions_app = self.routes to config / application.rb
match "/404", :to => "errors#not_found" to config/routes.rb match "/404", :to => "errors#not_found" to config / routes.rb
(and the appropriate controller/views). (以及适当的控制器/视图)。

The problem is we need ourdomain.com/id to display an index page for a product category of id . 问题是我们需要ourdomain.com/id来显示id产品类别的索引页面。

So, now ourdomain.com/404 shows our 404 page, when it should show our category listing page for the category with an id of 404. 所以,现在我们的ourdomain.com/404 404显示了我们的404页面,它应该显示id为404的类别的类别列表页面。

How can we work around this? 我们如何解决这个问题?
Is there a way to make the app prepend each error with error_ before it's evaluated by routes ? 有没有办法让应用程序在routes评估之前使用error_前置每个错误?
Or, maybe somehow set config.exceptions_app to reference a namespace in the routes file? 或者,也许以某种方式设置config.exceptions_app来引用routes文件中的命名空间?
Or, can I create a second route set and set config.exceptions_app = self.second_set_of_routes ? 或者,我可以创建第二个路由集并设置config.exceptions_app = self.second_set_of_routes吗?

Thanks! 谢谢!

We had the same problem -- error codes colliding with ids for resources at the root level (eg, collisions between ourdomain.com/:resource_id and ourdomain.com/404 ). 我们遇到了同样的问题 - 错误代码与根级别的资源的ID冲突(例如, ourdomain.com/:resource_idourdomain.com/404之间的冲突)。

We modified José Valim's solution by adding a route constraint that only applies when handling an exception: 我们通过添加仅在处理异常时应用的路由约束来修改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

(We only stumbled on this solution last night, so it hasn't had much burn-in time. We are using Rails 3.2.8) (昨晚我们偶然发现了这个解决方案,所以没有太多刻录时间。我们正在使用Rails 3.2.8)

It seems that this route is hard coded at the show_exceptions method ( see source ) 似乎这个路由在show_exceptions方法中是硬编码的( 参见源代码

Sorry, but I don't think of a way of doing it besides changing the line 45 on the source above to: 抱歉,除了将上面的源代码行45更改为以下内容之外,我没有想到这样做的方法:

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

(what is, needless to say, no solution at all). (不用说,根本没有解决方案)。

It doesn't hurt to ask:If you thought it was nice to have your own error controller implemented so simply and desperately want to have it, than wouldn't it even be more "RESTful" if your route were yourdomain.com/product/:id? 问:如果你认为让你自己的错误控制器实现如此简单并且非常想要拥有它,那就好了,如果你的路线是yourdomain.com/product,它甚至不会更“RESTful” /:ID?

There's one solution which I've found so far: 到目前为止我找到了一个解决方案:

# 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 is the method that Rails calls to handle most errors. rescue_action_in_public是Rails调用以处理大多数错误的方法。
local_request? the method tells Rails to stop sucking if it's local request 该方法告诉Rails如果是本地请求则停止吸吮

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

It simply says that it can't find any other route to handle the request (ie the *path ) it should call the rescue_404 action on the application controller (the first method above). 它只是说它找不到任何其他路由来处理请求(即*path )它应该在应用程序控制器上调用rescue_404动作(上面的第一种方法)。

EDIT 编辑

This version worked for me well! 这个版本对我有用! Try to add to application.rb 尝试添加到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

See: https://github.com/rails/rails/issues/671#issuecomment-1780159 请参阅: https//github.com/rails/rails/issues/671#issuecomment-1780159

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM