#7 new
sserdyuk

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

    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

    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

    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

    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.

New-ticket Create new ticket

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.

People watching this ticket

Pages