Custom Actions in Routes.rb

Hi, on rails 2.0.2 i generate a controller with actions Index and New using: "script/generate controller Recipe Index New"

I can now access the actions index/new through /recipe/index or / recipe/new. But if i create a new blank action called delete using: "def delete end"

and create the corresponding view for delete action i cannot access it through /recipe/delete!

I've been told that this is because in restful routes i need to specify the new action delete (even though i never specified the actions index/new) and i have searched through the api but am still not clear on how exactly i would add a custom action route to routes.rb?

the action should be named destroy, not delete

if you want to define custom actions you must use something like this

map.resources :name, :member => ["my_action"] if it runs on a specific member and needs an id or map.resources :name, :collection => ["my_action"] if it's a more general action (like index) that does not need an id

I've learned that routes.rb is your friend and a great file to keep open to see how rails maps everything for you. This will show you how to access rails built-in futions. Also, Chapter 20 in Agile Web Development with Rails will help you understand what rails does with the all important routes in 2.0

So: restful routes automatically handles seven controller actions for you: index, new, create, edit, update, show, and destroy.

index, show, new, and edit are handled as GETs to (respectively) recipes/ recipes/1 recipes/new recipes/1/edit

create is handled by a POST to recipes/; update handled by a PUT to recipes/1; destroy handled by a DELETE to recipes/1.

Whoever said "you should call it destroy"; buzzer sound for you. #destroy is the method name we use for the end of a DELETE request. But what if you want a page up front to handle the "are you sure you want to destroy?" dialogue? That would be a GET to /1/delete (just like our edit method). So, in our routes file:

map.resources :recipes, :member => {:delete => :get}

will allow you to GET recipes/1/delete with delete_recipe_path . What this translates as is: I should be able to GET the page "delete" on any individual recipe. If you wanted to have a new route on top of every recipe, you could do the following:

map.resources :recipes, :collection => {:list => :get}

which allows you to GET recipes/list with list_recipes_path . This means: I should be able to GET a list of ALL recipes.

Obviously, this should ONLY be for a page you display. If there's any destruction in your action, you're looking for a DELETE to a recipe path.

But the way you add extra routes on is through the :collection and :member hashes in your routes file. Does that help?

If in doubt, type rake routes at the terminal, to see what routes your app currently supports.

Does this mean that for every custom action I define in a controller, I have to add it in my routes.rb?

What if I had 50 custom actions? ...for the sake of hypothetical argument. This doesn't seem so dynamic to me.

You won’t have 50 custom actions, believe me.

Have a read of http://frozenplague.net/2008/01/06/restful-routing-an-overview/ and http://frozenplague.net/2008/03/16/administration-namespacing/

Ok, I read your articles and I think I'm beginning to understand routes (will need to read more).

I'm attempting to build a web application that will communicate with some unix and windows servers and will be running binaries and executables on those boxes which is why I need to run custom actions. So this is not just a web site driven by ROR, but more of a full application. I'm trying to avoid mixing in other languages e.g. CGI with Perl, Javascript unless I really, really have to.

Ryan Bigg wrote: