views:

32

answers:

2

Hi,

I add this line in my routes.rb file

map.connect ':controller/:action/:id/:title', :controller => "recipes"

thinking that I am adding the recipe title at the end of the URL and this would only apply to the recipe controller. I have also declared a resource at the beginning of the file like this

map.resources :recipes

The following URL works perfectly fine

http://localhost:3000/recipes/show/84/testing201
http://localhost:3000/recipes/edit/84/testing2010

However, when I say rake routes I get the following for the recipe controller

recipes GET    /recipes(.:format)                 {:controller=>"recipes", :action=>"index"}
             POST   /recipes(.:format)                 {:controller=>"recipes", :action=>"create"}
  new_recipe GET    /recipes/new(.:format)             {:controller=>"recipes", :action=>"new"}
 edit_recipe GET    /recipes/:id/edit(.:format)        {:controller=>"recipes", :action=>"edit"}
      recipe GET    /recipes/:id(.:format)             {:controller=>"recipes", :action=>"show"}
             PUT    /recipes/:id(.:format)             {:controller=>"recipes", :action=>"update"}
             DELETE /recipes/:id(.:format)             {:controller=>"recipes", :action=>"destroy"}

and at the bottom I see this

/:controller/:action/:id/:title    
/:controller/:action/:id           
/:controller/:action/:id(.:format) 

From the output it seems like the title is not applied to the recipe route but it is applied at a global level. How can I fix this, so the wildcard symbol (":title" in "/:controller/:action/:id/:title") is only applicable to the recipes?

A: 

You are mixing two different routing concepts. One is RESTful routes (go read about it on google) and the other is generic/general route. You should use just one of them. RESTful one is recommended (map.resources :recipes). But first you need to decide which one to use.

Plus this definition is wrong:

map.connect ':controller/:action/:id/:title', :controller => "recipes"

You have :controller variable in the routes and then you say that :controller should be bound to 'recipes'. One way to fix it is this:

map.connect '/recipes/:action/:id', :controller => "recipes"

or better

map.connect '/recipes/:id/:action', :controller => "recipes"

and you're getting closer to RESTful routes.

If you want the title in your routes, then go with named route coupled with RESTful resource. But don't mix :id and :title in one route. Use just one parameter (or both combined but that's another story).

map.resources :recipes, :except => [:show]
map.recipe '/recipe/:title', :controller => 'recipes', :action => 'show'

And you would probably need to override the to_param method in your Recipe model:

def Recipe < ActiveRecord::Base
  def to_param
     title
  end
end
Paweł Gościcki
Thanks for the info, it works expected. However, the default edit link(http://localhost:3000/recipes/84/edit/) results in an error. It looks like it is trying the "show" action instead of the "edit". map.resources :recipes, :except => [:show]map.recipe '/recipes/:id/:title', :controller => "recipes", :action => "show" Any ideas?
iHeartDucks
/recipes/:id/:title -> again, this is wrong; use either :id or :title and use singular form, so it does not conflict with map.recipes, like this: `map.recipe '/recipe/:id', :controller => 'recipes', :action => 'show'
Paweł Gościcki
I don't think I should move away from the defaults that rails provide. So I have decided to change the format of the show url to something like this http://localhost:3000/recipes/84-testing2010. I provided my own definition of to_param and this seems to work.
iHeartDucks
A: 

i would comment the map.resources, comment the connect and do it one more time with map.with_options:

map.with_options :controller => 'recipes' do |recipes|
 recipes.list '', :action => 'index'
 recipes.delete '/delete/:id/:title', :action => 'delete'
 recipes.edit '/edit/:id/:title', :action => 'edit'
end
VP
I think it's best to stick with the RESTful way of doing things. I just changed the format of the URL (localhost:3000/recipes/84-testing2010) and this seems to work fine.
iHeartDucks