# Custom REST routes

**URL:** <https://www.ruby-forum.com/t/custom-rest-routes/115507>\
**Category:** Rails\
**Created:** [September 25, 2007, 9:30pm UTC](https://www.ruby-forum.com/t/custom-rest-routes/115507 "2007-09-25T21:30:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![daz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@daz](https://www.ruby-forum.com/u/daz)\
**Post date:** [September 25, 2007, 9:30pm UTC](https://www.ruby-forum.com/t/custom-rest-routes/115507/1 "2007-09-25T21:30:47Z")

</div>

Is there any way of getting the nice url methods such as new\_page\_path  
that you get when you declare

map.resource :pages

in routes.rb?

Here is my situation:  
I have a Page model with lots of pages that use acts\_as\_list. This  
means that some of the pages are root pages - these are my site’s  
sections (tabbed navigation). I would like the urls to look like this:

[www.myapp.co.uk/blog/awesome-post](http://www.myapp.co.uk/blog/awesome-post)

This will take you to a page called ‘awesome-post’ that is a child of  
a page called blog. Each page has a parent page (the ‘page\_id’ field  
in the database).

In routes.rb, I have:

map.page ‘:section/\*pages’, :controller =\> ‘pages’, :action =\> ‘show’

This works fine and gives me access to params[:section] and an array,  
params[:pages] which can be used to find the page I am looking for.

What I want to be able to do is create a new page that is a child of  
the ‘programmers’ page using the url

[www.myapp.co.uk/about/people/programmers/new](http://www.myapp.co.uk/about/people/programmers/new)

I can then grab params[:pages].last.id and use this to set the page\_id  
in the create action.

Do I just use  
map.new\_page ‘\*pages/new’, :controller =\> :pages, :action =\> ‘new’

Also, how do I ‘fake out’ the put and delete methods manually, if I  
want to do similar things to delete pages?

Sorry for the long post.

DAZ

---

<div class="post-metadata">

**Author:** ![daz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@daz](https://www.ruby-forum.com/u/daz)\
**Post date:** [September 25, 2007, 9:57pm UTC](https://www.ruby-forum.com/t/custom-rest-routes/115507/2 "2007-09-25T21:57:52Z")

</div>

I’ve found that if I add the line  
map.resources :pages  
to routes.rb, then I do get the full REST functionality, but I have to  
use urls such as

[www.myapp.co.uk/pages/new](http://www.myapp.co.uk/pages/new)

What I want is to efectively ‘namespace’ the pages, so you go to

[www.myapp.co.uk/blog/new](http://www.myapp.co.uk/blog/new)

if you want to add a new child page of blog, and

[www.myapp.co.uk/about/people/programmers/new](http://www.myapp.co.uk/about/people/programmers/new)

if I want a new page that is a child of the programmers page, that is  
a child of the people page, that is a child of the about page.

Can I do this?

DAZ

---

<div class="post-metadata">

**Author:** ![daz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@daz](https://www.ruby-forum.com/u/daz)\
**Post date:** [September 25, 2007, 10:02pm UTC](https://www.ruby-forum.com/t/custom-rest-routes/115507/3 "2007-09-25T22:02:32Z")

</div>

map.resources :people do  
map.resources :programmers  
end

will get you “/people/programmers/#{method}”

However, be careful of this going too deep:  
[http://weblog.jamisbuck.org/2007/2/5/nesting-resources](http://weblog.jamisbuck.org/2007/2/5/nesting-resources)

Jason

---

<div class="post-metadata">

**Author:** ![daz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@daz](https://www.ruby-forum.com/u/daz)\
**Post date:** [September 25, 2007, 10:16pm UTC](https://www.ruby-forum.com/t/custom-rest-routes/115507/4 "2007-09-25T22:16:40Z")

</div>

Thanks, but wouldn’t I only do that if people and programmers were  
models? The only model is pages - people and programmers are just  
examples of what the pages might be, they could be anything.

This route:

map.new ‘\*pages/new’, :controller =\> ‘pages’, :action =\> ‘new’

allows me to use urls like

[www.myapp.co.uk/news/latest/new](http://www.myapp.co.uk/news/latest/new)

I can then use params[:pages].last to grab the page with a permalink  
of ‘latest’ and use its id to set the page\_id of the new page. This  
will mean that the new page is a child of the ‘latest’ page.

Only problem is now that I don’t know where to send the form, with  
normal map.resources :pages, it was:  
\<% form\_for(:page, :url =\> pages\_path) do |f| %\>

Do I need to write my own create route?  
map.create ???  
I wouldn’t even know what to put in here since it never actually goes  
to an actual page, just accesses the ‘create’ action.

---

<div class="post-metadata">

**Author:** ![daz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@daz](https://www.ruby-forum.com/u/daz)\
**Post date:** [September 25, 2007, 11:08pm UTC](https://www.ruby-forum.com/t/custom-rest-routes/115507/5 "2007-09-25T23:08:10Z")

</div>

map.edit ‘:section/\*pages;edit’, :controller =\> ‘pages’, :action =\>  
‘edit’

works!

Going to

[www.myapp.co.uk/contact;edit](http://www.myapp.co.uk/contact;edit)

allows you to edit the contact page.

The only thing I don’t know how to do know is what to put in my forms  
to access the ‘create’ and ‘update’ actions.  
REST would have me use the same url but just using different methods  
(POST and PUT respectively), how does map.resources do that???

thanks again,

DAZ
