Namespaced controllers only work with namespaced routes
Reported by sserdyuk | September 29th, 2009 @ 11:11 PM
I have two resources:
map.resources :events do |event| event.resources :participants,
:controller => 'events/participants'
end
As you can see Participants controller is namespaced under 'events' just to keep things organized (I've got many other controllers like that). The route is not namespaced but only nested.
When I access '/events/4/participants', it blows up with 'wrong constant name 4' trying to classify '4'. The reason is that RequestPathIntrospection#namespace_segments assumes that controller's namespace will be present in the request_path as a static prefix, just like namespaced routes do it. It is not true in the case above.
The fix:
I think that #namespace_segments should be more selective and only assume that the namespace prefix is in the path if it is immediately followed by the current segment. See the implementation below.
The catch:
If parent resource ('events' in my case) is a singleton, this would still not work as request path would exactly match namespaced controller's path and '/event' would get chopped off. I do not have a better solution at this point, and I am not likely to look for it, as it is not the case in my application.
def namespace_segments
namespace = controller_path.sub(%r(#{controller_name}$), '')
request_path =~ %r(^/#{namespace}/#{current_segment}) ? namespace.split('/') : []
end
Comments and changes to this ticket
-
Ian White September 30th, 2009 @ 07:32 AM
Yes, this feature is designed with the :namespace option in mind. I can see that your intended use should be supported though.
How about an option :extract_namespace, which defaults to true, but could be turned off
class Events::Participants < ApplicationController resources_controller_for :participants, :extract_namespace => false end
-
Ian White September 30th, 2009 @ 07:47 AM
I think that #namespace_segments should be more selective and only assume that the namespace prefix is in the path if it > is immediately followed by the current segment. See the implementation below.
I don't think this approach will work in the case where a controller is invoked with a wildcard nesting path (a common use case)
map.namespace :admin do |admin| admin.resources :forums admin.resources :users, :has_many => :forums end class Admin::ForumsController resources_controller_for :forums # this controller handles /admin/forums, and /admin/users/:id/forums end
When requesting
'/admin/forums/1'
your proposal works fine, but when requesting'/admin/users/1/forums'
it will break as the namespace won't be processed.So, would you be happy for an option which turns namespacing off completely? (as outlined above)
-
Ian White September 30th, 2009 @ 07:49 AM
btw. namespace processing is required for routes created with :namespace, because of the name prefixes routing creates for named routes.
-
Ian White October 8th, 2009 @ 02:01 PM
Hi,
I have been trying to move away from relying on rails routing internals for rc, since these are part of the private API, and subject to change resulting in weird breakage.
But, perhaps my approach is not the same as yours. Could you make a fork on github with the changes you mention above, as a proof of concept please?
Cheers,
Ian
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป
resources_controller is a rails plugin that eases the pain of RESTful controllers.