#79
Nov 11, 2007

Generate Named Routes

This more advanced episode will show you how to dynamically generate named routes by adding a method to the map object.
Tags: routing
Download (9.2 MB, 5:59)
alternative download for iPod & Apple TV (7.4 MB, 5:59)

Update: there’s now a plugin which does this called static_actions.

Resources

# routes.rb
ActionController::Routing::Routes.draw do |map|
  def map.controller_actions(controller, actions)
    actions.each do |action|
      self.send("#{controller}_#{action}", "#{controller}/#{action}", :controller => controller, :action => action)
    end
  end
  
  map.resources :products, :categories
  
  map.controller_actions 'about', %w[company privacy license]
end

RSS Feed for Episode Comments 25 comments

1. Brian Mitchell Nov 12, 2007 at 01:29

While I generally do use simple methods like you defined above on map, I will sometimes take a different approach for those types of urls.

I generally start applications by removing the :c/:a/:id style routes and add a "site" controller for general site topics. The routes file might look like this at first:

map.site ':action', :controller => 'site'

This works well enough since it can be used pretty cleanly:

site_path('jobs') #=> /jobs

There are some pros and cons here. One is that the actions can be added easily, which is a good thing in initial development... but if you like to strictly protect interfaces exposed on the web, then you can add some constraints on action:

map.site ':action', :controller => 'site', :action => /(jobs|sitemap|about)/

That regular expression will ensure only certain actions can get called ( the ()'s are required to correctly match given the |'s -- in 1.2 at least).

Finally, I should note that it is rather easy to add a formatted route as well:

# here is where things like with_options help a little.
map.site ':action', :controller => 'site'
map.site ':action.:format', :controller => 'site'

site_path('jobs') #=> /jobs
site_path('sitemap', 'xml') #=> /sitemap.xml

This might come in handy if you have several types of clients connecting to your service.

Of course, there are probably places where the overhead of these slightly more dynamic routes might be harmful.


2. Brian Nov 12, 2007 at 11:57

The one problem I keep having with routing is when you don't want the controller name in the route. For example, if you're doing a location based app, /texas/dallas/ is a lot more natural than /states/texas/cities/dallas. I do keep running in to a problem where two objects have the same scope, but you want to redirect to one if not found. i.e. /united-states/texas vs. /germany/munich. The way I've done this is ugly, but it works...kinda. Any suggestions would be helpful. I think there's a lot of voodoo with routing to most people.


3. Henrik N Nov 13, 2007 at 00:31

Brian: If worst comes to worst, you can have a catch-all route and do logic in a controller: http://railscasts.com/episodes/46

A very interesting, but pretty ugly/hackish way to use more powerful logic in your routes is http://www.ruby-forum.com/topic/42505.


4. lester bangs Nov 14, 2007 at 17:23

did you say "dick around" near the end there? ryan, i'm shocked! :)


5. James Nov 16, 2007 at 21:17

@lester - He said "dig around"! He has referred to "digging" in the past, so I am sure he is not a potty mouth. You have got your mind in the gutter! ;)


6. andré camargo Nov 16, 2007 at 23:40

Ryan, many thanks for every single episode. It's fantastic how you show the world of ruby, rails and the whole thing interact together. :-)

Keep your good work, thanks again!


7. Paul Barry Nov 19, 2007 at 06:32

It seems to me that this is meta just for the sake of being meta. Maybe that's just something you wanted to show in the screencast, but this seems like a cleaner way to do it:

%w{company privacy license}.each do |a|
  map.send "about_#{a}", "about/#{a}", :controller => 'about', :action => a
end


8. Ryan Bates Nov 20, 2007 at 10:20

@Paul, I agree this is an over-refactoring. It works best if you have quite a few of these kinds of actions in multiple controllers. That scenario was too complex for a simple screencast so I stuck with one controller.

In this case it's more about the technique then the circumstances to use it (which varies from project to project). I should have made that more clear.

@lester, LOL. I said "dig" around. I'll blame it on the cold I'm getting.


9. Drew Dec 06, 2007 at 12:43

Why create a method on map when you could simply send the actions to the map object?

def controller_paths(controller,*actions)
  actions.each do |a|
    map.send(#{controller}_#{a},#{controller/a},:controller => controller, :action => a)
  end
end

controller_paths :about, :company, :privacy, :liscense


10. Adrian Dec 11, 2007 at 01:19

A general question about routes:
Is there a naming convention between the route and the model relations?

model:
has_many usercomment
has_many usercomments, :through => usercomment

route:
map.resources :users do |users|
  users.resources :usercomments
end

Would this one work?


11. kino May 23, 2008 at 01:53

The Categories would thereby be made to contradict, consequently, the things in themselves.


12. Faktura Jun 15, 2008 at 00:25

Very useful cast!


13. Sukhwinder Singh Tambar Sep 30, 2008 at 01:21

Really usefull cast...


14. fiesta online money Nov 20, 2008 at 17:39

Thanks Ryan,I think this is one of the most wonderful sites. I have great admiration for you.


15. aoc gold Nov 21, 2008 at 19:19

I have great admiration for you.


16. barcode freeware Nov 26, 2008 at 21:49

Enterprise barcode maker tool generate professional security tags or stickers.


17. lily Nov 27, 2008 at 18:46

Thank you Ryan, your screencast is good. Please look at our URL, if necessary we can learn from each other.


18. Data Recovery Prices Nov 28, 2008 at 21:01

Flash card data recovery application restores audio video clips, pictures, documents.


19. evden eve nakliyat Dec 01, 2008 at 01:07

evden eve nakliyat


20. Accounting Program Dec 03, 2008 at 02:04

Costume invoice program with advance barcode data access feature for enterprises.


21. Accounting Program Dec 03, 2008 at 02:04

Costume invoice program with advance barcode data access feature for enterprises.


22. Accounting Program Dec 03, 2008 at 02:04

Costume invoice program with advance barcode data access feature for enterprises.


23. Accounting Program Dec 03, 2008 at 02:04

Costume invoice program with advance barcode data access feature for enterprises.


24. wow patch 3.0.4 Dec 03, 2008 at 18:53

good, thanks for your infos


25. Invoice program Dec 03, 2008 at 21:46

Providing the services of free invoice software to manage billing records of an enterprise

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player