It sounds like it is generally recommended either not to nest
controllers at
all or at most by one level. However this seems to relate mostly to
resources. Interactive functionality generally works well with
resources,
but for a complete website there is often additional content that
contains
information not suitable for resources, but that still uses the same
views
mechanism for consistency.
I’ve got some resources and also some content that doesn’t suit using
resources and it is convenient to store the content in hierarchical
directories (?namespaces). The content is written as rails views. All
worked
OK under rails 2 but I’m struggling to get routing to work under rails
3.
For example if you have an app/views directory structure such as:
views >
level1
level2
level3
and would to place views at each of these levels, including an index
action,
what is the best way to create route(s) in routes.rb to accommodate
this?
Using the default wildcard route of match
‘:controller(/:action(/:id(.:format)))’ results in the top level working
but
the index action for level2 results in an action not known for level1
controller from the router.
I’ve experiemented with various combinations of namespace, scope and
match
statements, but none seem to cater for this seemingly simple requirement
to
match a nested set of views to urls.
Maybe I’m missing a trick here - is there a better way to structure
hierarchical non-resource content but still use the facilities in the
rails
framework? I guess I could combine rails with some other framework, but
would like to keep everything within rails if possible.
The problem is very specific, so would be hard to quickly find a
solution
with the information you have posted.
Would be good if you can post the routes file from your Rails 2 app
which
used to work fine and the best working version of routes file from Rails
3
app.
You may also want to read up the guide on Rails 3 routing -
Read section - 3.11 - Route Globbing, that may do the trick for you.
namespace “levelx” do
namespace “levely” do
namespace “levelz” do
match ‘levelzcontrollerone(/:action)’ => ‘levelzcontrollerone#’
match ‘:action’ => ‘#’
root :to => ‘levelz#index’
end
match ‘levelycontrollerone(/:action)’ => ‘levelycontrollerone#’
match ‘:action’ => ‘#’
root :to => ‘levely#index’
end
match ‘levelxcontrollerone(/:action)’ => ‘levelxcontrollerone#’
match ‘:action’ => ‘#’
root :to => ‘levelx#index’
end
A direct conversion to the routes you had in Rails 2, would be something
like this:
match ‘level1/level2/level3/:action’, :controller =>
‘level1/level2/level3’
match ‘level1/level2/:action’, :controller => ‘level1/level2’
match ‘:controller/:action/:id’
There would be a better way of doing this with namespace or scope, but
if
this works fine, then let it be.
Don’t suppose anyone has a moment to give me a pointer on this one?
I’ve tried the following:
namespace “levelx” do
namespace “levely” do
namespace “levelz” do
root :to => ‘levelz#index’
end
root :to => ‘levely#index’
end
root :to => ‘levelx#index’’
end
This provides default routes for each namespace, but you then can’t
access
any other controllers at each level of namespace. You can’t specify a
:controller segment, so adding match “:controller(/:action)” within each
namespace block is not an option.
I’ve also tried:
match ‘/levelx/levely/levelz/:controller(/:action)’
match ‘/levelx/levely/levelz’ => ‘levelx/levely/levelz#index’
match ‘/levelx/levely/:controller(/:action)’
match ‘/levelx/levely’ => ‘levelx/levely#index’
match ‘/levelx/:controller(/:action)’
match ‘/levelx’ => ‘levelx#index’
Which again seems to route index actions OK but not other controllers
within
each namespace.
I’ve tried:
match ‘/levelx/levely/levelz/:controller(/:action)’, :controller =>
/levelx/levely/levelz*/
match ‘/levelx/levely/:controller(/:action)’, :controller =>
/levelx/levely*/
match ‘/levelx/:controller(/:action)’, :controller => /levelx/levely*/
match ‘/:controller(/:action)’, :controller => /levelx*/
Which doesn’t seem to work.
What I’m really after is the equivalent of the match
‘/:controller(/:action)’ that will work with nested namespaces. If
constraints can be applied to top level namespaces then so much the
better.
Maybe time to admit defeat and abandon rails for this type of website,
which
would be a shame since the rails framework is great for teh rest of the
resource-based parts of the site. More likely I’m just being thick.