custom REST routes

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

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

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

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

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

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

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

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

Jason

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

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.

map.edit ':section/*pages;edit', :controller => 'pages', :action => 'edit'

works!

Going to

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

There’s special checking for the request type, whether POST GET DELETE or PUT. Your controller actions get wrapped up in these checks when you setup these type of resources.

To do update and create, you’re looking at using:

Update: <% form_tag page_url(@page), :method => :put do %>

Create:

<% form_tag pages_url, :method => :post do %>

Also, grab this: http://topfunky.com/clients/peepcode/REST-cheatsheet.pdf it’s been an invaluable reference for this stuff to me.

Jason

Thanks Jason,

I think that the method you are describing will only work if I'm using map.resources :pages

But I want to avoid using that as it seems to force me into using paths of the form

/pages/:id

This is not what I want - I don't want the word 'pages' there and I want a drill down of page permalinks with the last one being the page being requested.

I have the cheatsheet already - it is very helpful.

cheers,

DAZ