resource with multiple routes

Hello folks.

My application has some resource types which exist at multiple places within the app. For example, for the discussion model, there are general discussions, and discussions specific to a particular group.

Things have worked out pretty well so far. My routes are defined as such:

map.resources :discussions do |d|
d.resources :discussion_messages
end

map.resources :groups do |g|
g.resources :discussions do |d|

d.resources :discussion_messages

end
end

And it doesn’t take much logic in my controller to make things work out.

However, I’m running into a problem with some of the url generators. For example, discussions_path. Ideally, discussions_path by itself would generate /discussions, and discussions_path @group would generate group/@group/discussions. However, discussions_path @group results in an error.

Is this configuration even supported by rails? Or do I need to bite the bullet and make two controllers, etc? Any way I could trick the routing and/or url generators into doing what I want?

Thanks for any pointers.

Hi --

Hello folks.

My application has some resource types which exist at multiple places within
the app. For example, for the discussion model, there are general
discussions, and discussions specific to a particular group.

Things have worked out pretty well so far. My routes are defined as such:

map.resources :discussions do |d|
  d.resources :discussion_messages
end

map.resources :groups do |g|
  g.resources :discussions do |d|
    d.resources :discussion_messages
  end
end

When you do d.resources :discussion_messages, you're getting a bunch
of named route methods: discussion_messages_url,
discussion_message_url, etc. But you've done this twice, so the second
set clobbers the first set.

In other words, you can't have two named routes with the same name
distinguished only by their method signature. There can only be one
with a given name.

So... you probably want to use the :name_prefix specifier -- something
along the lines of:

  map.resources :groups do |g|
    g.resources :discussions, :name_prefix => "group_" do |d|
      d.resources :discussion_messages, :name_prefix => "group_"
    end
  end

Then you can do:

  discussions_path
  group_discussions_path(@group)

and so forth.

David

Thanks so much David, that succinctly explains why I too have been
having problems with my routes from time to time. Sure wish that was
made clearer in the Rails docs.

Jeff

Wow, thanks David! This is exactly the level-of-indirection that I was
looking for but figured did not exist. It works perfectly.

This inspires two questions:

[1] Where (if anywhere) in the rails documentation is the :name_prefix
flag documented? Or any of the routing features, for that matter? Does
it blow anyone else's mind that there is only one hit on google for
"ActionController::Routing::Routes"?

[2] My current solution for differentiating between the two discussion
realms in my controller is to overwrite
ApplicationController.default_template_name as follows:

def default_template_name(action_name = self.action_name)
  if action_name
    action_name = action_name.to_s
    if action_name.include?('/') && template_path_includes_controller?
(action_name)
      action_name = strip_out_controller(action_name)
    end
  end
  context = @group ? 'group_' : 'global_'
  "#{self.class.controller_path}/#{context}#{action_name}"
end

(Everything is the same other than the addition of the penultimate
line and the modification of the last line).

Is there a better way to do this?

Thanks
John