我们最近将 Rails 3.2.16 应用程序升级到 Ruby 2.1.0。我开始在我们的一些遗留路由上看到路由错误,这些路由仅依赖于模式匹配:
match ':controller(/:action(/:id(.:format)))'
我发现我们有一个控制器,其动作与另一个顶级控制器的“控制器名称”相匹配。例如:
class FoosController < ApplicationController
end
class BarsController < ApplicationController
def foos
end
end
Rails 正在尝试路由/bars/foos/19.json
到FoosController#19
而不是BarsController#foos
使用:id
参数 19。
最终,我将其追溯到ActiveSupport::Inflector.constantize
,并且该行为很容易重现:
001:0> class Foo; end
nil
002:0> class Bar; end
nil
003:0> Bar::Foo.name
(irb):3: warning: toplevel constant Foo referenced by Bar::Foo
"Foo"
这不是错的吗?它应该引发 aNameError
因为Bar::Foo
未定义。这目前正在破坏我们的路由,但我想它也可能会破坏很多其他地方。
2014 年 3 月 18 日更新:我能够在 irb Ruby 1.9.3(没有 Rails)中重现同样的行为,所以这不是问题constantize
,否则它是constantize
Ruby 2.1.0 中的问题。
实际的类名是PduFirmwareUpgradeController
(具有#pdus
动作)和PdusController
. 除了将操作重命名为独特的名称之外,我不确定我还能做什么。