# Routing nested resources

**URL:** <https://www.ruby-forum.com/t/routing-nested-resources/123833>\
**Category:** Rails\
**Created:** [December 21, 2007, 3:13am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833 "2007-12-21T03:13:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 3:13am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/1 "2007-12-21T03:13:21Z")

</div>

I’ve noticed that nested resources are also available via the default  
route:

In my application I have many gamers and want to give them a singleton  
profile resource ([example.com/gamers/3/profile](http://example.com/gamers/3/profile)). So my config.routes  
includes:  
map.resources :gamers, :has\_one =\> [:profile]

Even though it’s a singleton, my controller has be pluralized: called  
ProfilesController and live at app/controllers/profiles\_controller.rb  
with views in app/views/profiles.

The problem I see is that the default route also means that the  
profiles controller can be accessed at [example.com/profiles](http://example.com/profiles). Should I  
write a before\_filter to raise 404 if it can’t find params[:gamer\_id]?  
It seems the natural place to do this would be config/routes, but the  
only way to do that would be to remove the default route and  
explicitly list all of my other controllers. Is there a nicer way to  
do this that I’m missing?

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 3:20am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/2 "2007-12-21T03:20:57Z")

</div>

A question I’m tempted to ask is: why do you need to separate a gamer  
and  
their profile? Why not just store the profile information on a gamer?

–  
Ryan B.

> **[frozenplague.net](http://www.frozenplague.net)**
>
> This domain may be for sale!

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 3:28am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/3 "2007-12-21T03:28:34Z")

</div>

On Dec 20, 9:20 pm, “Ryan B.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> A question I’m tempted to ask is: why do you need to separate a gamer and  
> their profile? Why not just store the profile information on a gamer?

I’m going to be adding several sub-controllers to my gamers  
controller; I just gave this as the simplest example. You’re right  
that it makes sense to store profiles on the gamer objects.

Anyone have a solution for the routing, though?

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 4:33am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/4 "2007-12-21T04:33:29Z")

</div>

On Dec 20, 9:40 pm, “Ryan B.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Defining a before\_filter seems like the least painful way to go about it.

Hm, it doesn’t seem to be testable. I wrote:

def nested  
puts request.url  
raise ActionController::RoutingError, ‘not nested’ unless  
params[:gamer\_id]  
end

And that works fine. But when I try to test an action:

def test\_edit  
alice = gamers(:alice)  
# and any of the following:  
get :show, :gamer =\> alice  
get :show, :gamer =\> alice.to\_param  
get :show, :gamer\_id =\> alice  
get :show, :gamer\_id =\> alice.to\_param  
end

I just get the RoutingError… it says I’m requesting the url  
[http://test.host/profiles/edit/alice](http://test.host/profiles/edit/alice) instead of the correct url of  
[http://test.host/gamers/alice/profile/edit](http://test.host/gamers/alice/profile/edit). How do I tell the  
functional test to use the more-specific (and earlier in  
config.routes!) route instead of the default route?

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 3:41am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/5 "2007-12-21T03:41:29Z")

</div>

Defining a before\_filter seems like the least painful way to go about  
it.

On Dec 21, 2007 12:58 PM, Peter H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Anyone have a solution for the routing, though?
> 
> >

–  
Ryan B.

> **[frozenplague.net](http://www.frozenplague.net)**
>
> This domain may be for sale!

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 5:08am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/6 "2007-12-21T05:08:34Z")

</div>

I’d rather serve a 404 than 301 in this case.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 5:17am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/7 "2007-12-21T05:17:55Z")

</div>

raise the RoutingError and then say in your tests that the show page  
should  
raise error. I’ve only ever done RSpec testing so I’m not much help on  
the  
baked-in Rails testing front.

On Dec 21, 2007 2:37 PM, Peter H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’d rather serve a 404 than 301 in this case.
> 
> >

–  
Ryan B.

> **[frozenplague.net](http://www.frozenplague.net)**
>
> This domain may be for sale!

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [December 21, 2007, 4:35am UTC](https://www.ruby-forum.com/t/routing-nested-resources/123833/8 "2007-12-21T04:35:15Z")

</div>

What’s wrong with doing it a little simpler?  
private  
def check\_for\_gamer\_id  
redirect\_back\_or\_default(default\_controllers\_path) if  
params[:gamer\_id].nil?  
end

–  
Ryan B.

> **[frozenplague.net](http://www.frozenplague.net)**
>
> This domain may be for sale!
