# Implementing URLs with more than 3 levels in Rails

**URL:** <https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369>\
**Category:** Rails\
**Created:** [May 12, 2006, 6:07pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369 "2006-05-12T18:07:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [May 12, 2006, 6:07pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369/1 "2006-05-12T18:07:58Z")

</div>

Hi There

I started using Rails recently, and I see it’s very easy for URLs that  
have up to 3 levels:

/:controller/:action/:id

But what do you do when you need more than 3?

For example, my current project should have an “admin” interface.  
Admin has several sub-interfaces, for example a “users” interface. And  
the admin/users interface has several actions, e.g. “add”, for each  
user ID.

Ideally, I’d like to be able to have URLs such as:

[www.example.com/admin/users/add/1](http://www.example.com/admin/users/add/1)

But this doesn’t seem to work very well with the Rails scheme and  
supporting methods, for example “link\_to” assuming :action in this  
case is “users”, :id is “add”, and 1, well, doesn’t exist 🙂

(of course it’s possible to have the “admin” namespace inferred from a  
session, but I’d like a more RESTful approach)

Would appereciate any tips of good ways to do this.

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [May 12, 2006, 6:11pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369/2 "2006-05-12T18:11:53Z")

</div>

> [www.example.com/admin/users/add/1](http://www.example.com/admin/users/add/1)

You can do this. The question is, how are you going to lay out the  
controllers? Will you have an admin\_users controller? Using routes, you  
could do:

map.connect ‘admin/users/:action/:id’, :controller =\> “admin\_users”

and you’d get what you wanted.

I believe there’s also a way to put controllers in a subfolder, but I  
have no experience with that. Anyone want to comment?

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [May 12, 2006, 7:03pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369/3 "2006-05-12T19:03:46Z")

</div>

Here’s an example I use to add the pagination parameters to the url

# we are going to add the pagination parameters to the url instead of

adding them as parameters

# this fixes alot of the caching problems

map.connect ‘pragmatic/:action/:id/:page’,  
:controller =\> ‘pragmatic’,  
:requirements =\> { :page =\> /\d+/},  
:page =\> nil

adding more than three parameters to a url is as simple as creating the  
route.

Charlie B.  
[http://www.recentrambles.com](http://www.recentrambles.com)

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [May 12, 2006, 8:54pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369/4 "2006-05-12T20:54:04Z")

</div>

Like Maurice said you can do “script/generate controller Admin/User” and  
you will get user\_controller.rb file in app/controllers/admin folder.  
Just remember that you can’t have admin\_controller.rb in app/controllers  
folder because it’s aleady the name of your group of controllers and  
you’ll get errors.

If you need some common functionality for all your admin controllers you  
could create admin\_something.rb controller in app/controllers with  
common functionality and inherit all other admin controllers from that.

This way you won’t have to mess with routes at all.

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [May 12, 2006, 8:40pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369/5 "2006-05-12T20:40:39Z")

</div>

This is done using modules.

For example,

create a file, /app/controllers/admin/user\_controller.rb

and just make sure that in this file, UserController is inside the Admin  
module:

module Admin  
class UserController \< ActionController::Base  
…  
end  
end

Routes are then smart enough to figure this out. For example the route,  
/:controller/:action, would map the URL ‘/admin/user/add’ to the  
Admin::UserController#add method.

Hope this helps,

Maurice

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [May 13, 2006, 3:51pm UTC](https://www.ruby-forum.com/t/implementing-urls-with-more-than-3-levels-in-rails/60369/6 "2006-05-13T15:51:12Z")

</div>

On 5/12/06, szymek [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This way you won’t have to mess with routes at all.  
> Indeed, this is the best solution. I do:

ruby script/generate controller admin/users add

And then I have an Admin namespace, where I can put the various admin/  
controllers. This is indeed hadnled automatically (and very well) by  
Rails’ default routing settings. And since an Admin namespace is all I  
needed - both for request-handling and code-organization (in a neat,  
seperate subdirectory - it’s enough to take care of the task I  
presented.

However, it was good to learn about the available routes.rb methods.  
If at any point in the future I need a hierarchy beyond two levels  
deep after the controller (all I needed now was the regular 3-level  
/:controller/:action/:id inside an Admin namespace), I can simply add  
it to routes.rb thus:

ActionController::Routing::Routes.draw do |map|  
…  
map.connect ‘:controller/:action/:group/:id’  
…  
end

And then things like:

link\_to(‘Add user 21 to the “viewers” group’, ‘group’ =\> ‘viewers’, ‘id’  
=\> 21)

would work as expected. (Note: the above link\_to call would work well  
only inside the ‘admin/users’ namespace [which is reasonable for this  
use-case], the full parameters for getting the same URI from anywhere  
in the application is:

link\_to(‘Add user 21 to the “viewers” group’, :controller =\>  
‘admin/users’, :action =\> ‘add’, ‘group’ =\> ‘viewers’, ‘id’ =\> 21)  
)

* * *

-Alder
