# Param with map.resources

**URL:** <https://www.ruby-forum.com/t/param-with-map-resources/149893>\
**Category:** Rails\
**Created:** [September 30, 2008, 9:55pm UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893 "2008-09-30T21:55:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [September 30, 2008, 9:55pm UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893/1 "2008-09-30T21:55:57Z")

</div>

Hi all,

With ye olde routes, you could do stuff like:

map.connect ‘/foo/:id’, :controller =\> ‘bar’, :type =\> ‘foo’

but you can’t pass arbitrary params into #resources:

map.resources :foo, :controller =\> ‘bar’, :type =\> ‘foo’ # bonk!

the :controller key works fine, but :type is just ignored. This would  
be very handy for an STI-backed controller I have, to change a url  
like “/bar/new?type=foo” to “/foo/new” but still handle it with  
BarController.

I’ve seen a few people ask this question, eg.

[http://groups.google.com/group/rubyonrails-talk/browse\_frm/thread/ab38af850896baeb/384c7c3ef2a9f9cb?lnk=gst&q=params+resources#384c7c3ef2a9f9cb](http://groups.google.com/group/rubyonrails-talk/browse_frm/thread/ab38af850896baeb/384c7c3ef2a9f9cb?lnk=gst&q=params+resources#384c7c3ef2a9f9cb)

but no answers. I’ve tried a bunch of stuff  
with :requirements, :as, :path\_prefix, and nesting, but all to no  
avail. If anyone has any advice, I’d be most grateful.

Thanks,  
Ian

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [October 1, 2008, 3:20pm UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893/2 "2008-10-01T15:20:28Z")

</div>

Ian-  
It might be helpful if you gave a few more examples of what you want  
to accomplish. Are you trying to have the following routes all point  
to the “new” method on the same controller?

/foo/new  
/bar/new  
/somethingelse/new

Greg DeVore

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [October 2, 2008, 12:13am UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893/3 "2008-10-02T00:13:34Z")

</div>

Sure. You have it basically right, but let me elaborate.

I have models like so:

class Papa \< ActiveRecord::Base; abstract\_class = true; end  
class Daughter \< Papa; end  
class Son \< Papa; end

I have this controller:

class PapaController \< ApplicationController  
def new; @model = new\_model; end  
def new\_model  
params[:type].classify.constantize.new # there’s more safety logic  
here in reality, but this is the gist  
end  
end

I started with the default route:

map.resources :papa

So, then, I can create a new son by doing GET /papa/new?type=son,  
which is fine, but not ideal. Ideally, I would do GET /son/new, but it  
would still use the Papa controller, and set params[:type] to “son”.  
This is what I have right now:

map.resources :papa, :path\_prefix =\> ‘/:type’

which allows me to GET /son/papa/new, and create links like  
papa\_path(@model.type.to\_s.downcase, @model).

So the question is how to make these specs pass:

params\_from(:get, “/son/new”).should == {:controller =\> ‘papa’,  
:action =\> ‘new’, :type =\> ‘son’}  
params\_from(:get, “/daughter/new”).should == {:controller =\> ‘papa’,  
:action =\> ‘new’, :type =\> ‘daughter’}

Is that clearer?

Thanks,  
Ian

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [October 2, 2008, 6:18pm UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893/4 "2008-10-02T18:18:48Z")

</div>

It sounds like you want to be using nested resources. Try something  
like this

map.resources :papas, :has\_many =\> [:sons, :daughters]

For more info read…

[http://api.rubyonrails.org/classes/ActionController/Resources.html](http://api.rubyonrails.org/classes/ActionController/Resources.html)

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [October 2, 2008, 5:36am UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893/5 "2008-10-02T05:36:26Z")

</div>

Ian-  
I don’t know how you would do that in the way you are describing. One  
possibility though would be to do this:

map.resources :sons, :controller =\> “papas”  
map.resources :daughters, :controller =\> “papas”

This will point both routes to the papas controller. You won’t see  
“sons” or “daughters” come through as params. But you can query  
request.env[‘REQUEST\_URI’] and you would get back something like ‘/  
sons/new/’.

So:

1. request.env[‘REQUEST\_URI’].split("/") will give you an array  
["",“sons”,“new”]
2. access [1] of the array and you will have your parameter.

A little convoluted but I think that it would do what you want.

Greg

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [October 2, 2008, 8:46pm UTC](https://www.ruby-forum.com/t/param-with-map-resources/149893/6 "2008-10-02T20:46:11Z")

</div>

Wouldn’t that give me “/papas/1/sons/new”? Not exactly what I’m  
looking for if I understand it correctly, but thanks.
