#79 Generate Named Routes
This more advanced episode will show you how to dynamically generate named routes by adding a method to the map object.
- Download:
- mp4Full Size H.264 Video (7.75 MB)
- m4vSmaller H.264 Video (5.6 MB)
- webmFull Size VP8 Video (19.8 MB)
- ogvFull Size Theora Video (10.8 MB)
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.
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.
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.
did you say "dick around" near the end there? ryan, i'm shocked! :)
@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! ;)
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!
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
@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.
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
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?
Really usefull cast...
i'm trying to setup a route that's something like
map.connect ":foo/:controller/:action/:id", so i get :foo as a parameter.
that statement doesn't work in my routes.rb, but i'm a little confused about how to do it if it's possible at all (all the examples i've seen are of the form "controller"/"action"/[extra stuff]
any advice/suggestions would be greatly appreciated!
thanks!
Non-destructive data base conversion tool is designed for converting source database records to destination database records.
Barcode decoding software is easy to use program for both technical and non technical users
Provide software to enter image descriptions and support all picture file formats.
Providing inventory management application keep track on entire business process and make it smooth.