views:

367

answers:

4

I'm creating a Ruby on Rails app that consists of stories. Each story has multiple pages.

How can I set up routes.rb so that I can have URLs like this:

http://mysite.com/[story id]/[page id]

Like:

http://mysite.com/29/46

Currently I'm using this sort of setup:

http://mysite.com/stories/29/pages/46

Using:

ActionController::Routing::Routes.draw do |map|

  map.resources :stories, :has_many => :pages
  map.resources :pages

  map.root :controller => "stories", :action => "index"

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

end

Thanks in advance. I'm a newbie to Rails and routing seems a bit complicated to me right now.

+6  A: 

Here's a good resource.

map.connect 'stories/:story_id/:page_num', :controller => "stories", :action => "index", :page_id => nil

In your controller:

def index
  story = Story.find(params[:story_id])
  @page = story.pages[params[:page_num]]
end

UPDATE: Just noticed you don't want 'stories' to appear. Not sure if dropping that from the map.connect will work... try it out.

map.connect '/:story_id/:page_num', ...
Terry Lorber
Thanks! Still working out how exactly to utilize the controller to pull the right page, but you've put me on the right track, at least.
Unniloct
After reading your update... map.connect '/:story_id/:page_id', ... works well enough (note the slash at the beginning)...but I don't know where to go from here.
Unniloct
A: 

Terry Lorber's answer, above, works very well, provided you don't forget the slash at the beginning of his revised solution, like so:

map.connect '/:story_id/:page_id', :controller => "pages", :action => "index", :page_id => nil

But I don't know where to go from here! How do I get the controller to go to the correct page?

Unniloct
+1  A: 

Given the route of

map.connect '/:story_id/:id', :controller => 'pages', :action => 'show'

You could do this in your controller

def show
  @story = Story.find(:story_id)
  @page = @story.pages.find(:id)
end

Now you can get the page using the story id.

PS: map.connect ':story_id/:id' should work.

Samuel
Your code snippet is not valid -- both your find calls are missing the params hash and just passing the symbol. `Story.find(:story_id)` should be `Story.find(params[:story_id])`
bjeanes
+1  A: 

I am not sure why no one has suggested just using a named route. Something like

map.story '/:story_id/:page_id', :controller => 'stories', :action => 'show'

then you could just call it with

story_path(story.id,params[:page})

or something similar.

Scott Miller
Because Unniloct didn't ask about that, he asked what to do to get the story and page, not link to it.
Samuel