我们最近将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"
这不是错的吗?它应该引发NameError
,因为Bar::Foo
未定义。这目前正在打破我们的路由,但我想它也可能打破很多其他地方。
更新2014年3月18日:我能够在irb Ruby 1.9.3(没有Rails)中重现相同的行为,所以它不是constantize
的问题,否则这是constantize
在Ruby 2.1.0中如何工作的问题。
实际的班级名称为PduFirmwareUpgradeController
(具有#pdus
操作)和PdusController
。除了将动作重命名为独特的东西之外,我不确定我能做些什么。