I am experiencing a weird problem on one of the 3 test servers I'm
using:
There is a controller named admin/statistics and I am trying to
access /admin/statistics
The matching rule is: map.connect ':controller/:action/:id'
On 2 of the 3 servers, recognize_path correctly matches to
Parameters: {"action"=>"index", "controller"=>"admin/statistics"}
But on the 3rd server here is what happens:
Parameters: {"action"=>"statistics", "controller"=>"admin"}
Of course that action does not exist, and it fails.
some more information
I ran the following function to search more detail:
#To show all the routes and their recognition
ActionController::Routing::Routes.routes.each do |route|
puts route
puts route.write_recognition
puts
end
And to my great surprise, despite exactly the same source, rails
version, ruby version, there was a difference:
In the "bad" server:
if (match = /\A\/(?i-:(rails_info|rails\/info|public|rest|admin|admin\/
teams>admin\/keywords|admin\/photos|admin\/car_situations|admin\/
circuits>admin\/statistics|admin\/update|admin\/communication|admin\/
users>admin\/dump|admin\/editor|admin\/photo_types|admin\/updates|admin
\/photo_styles|admin\/monitoring|admin\/database|admin\/jobs|admin\/
people>admin\/sponsors|admin\/sessions|admin\/import|admin\/customers|
admin\/synchronize|admin\/grand_prix|admin\/photo_angles|admin\/races|
admin\/posts|admin\/settings|admin\/emotions))(?:\/?\Z|\/([^\/;.,?]+)
(?:\/?\Z|\/([^\/;.,?]+)\/?))\Z/.match(path))
In the "good" servers:
if (match = /\A\/(?i-:(rails_info|rails\/info|public|admin\/teams|admin
\/keywords|admin\/photos|admin\/car_situations|admin\/circuits|admin\/
statistics>admin\/update|admin\/communication|admin\/users|admin\/dump|
admin\/editor|admin\/photo_types|admin\/updates|admin\/photo_styles|
admin\/jobs|admin\/monitoring|admin\/database|admin\/people|admin\/
sponsors>admin\/sessions|admin\/import|admin\/customers|admin\/
synchronize>admin\/grand_prix|admin\/photo_angles|admin\/races|admin\/
posts>admin\/settings|admin\/emotions|rest|admin))(?:\/?\Z|\/([^\/;.,?]
+)(?:\/?\Z|\/([^\/;.,?]+)\/?))\Z/.match(path))
In other word rest|admin is added on the non-working servers too
early...
"Sounds like a print the node before the subnodes"
Problem was solved, and comes from an error in actionpack:
in /actionpack-1.13.3/lib/action_controller/routing.rb line 290
Dir["#{load_path}/**/*_controller.rb"].collect is not a constant order
depending on the file system, and apparently not the good order for
checking for possible routings(since the regular expression to match
routings is based on the order given by this).
A simple fix is to add a sort:
Dir["#{load_path}/**/*_controller.rb"].sort.collect
After that everything works fine, and the order will be constant
amongst filesystems.