Dynamic generation of routes based on db contents

Hello all,

I am working on a project that requires the ability to dynamically add one-level routes based on person name and city.

So, at any given time, someone might go to:

http://www.myapp.com/JakeCutter http://www.myapp.com/LosAngeles

And the app needs to be smart enough to determine whether the data passed after / is a user name or a city name.

Each of these potential values are stored in the database, so my first thought was to dynamically generate it *in* routes.rb using AR.

User.find(:all).each do |u|   map.connect "/#{u.first_and_last_name}", :controller=>UsersController, :action=>:detail, :id=>u.id end

Location.find(:all).each do | loc |   map.connect "/#{loc.city}", :controller=>LocationController, :action=>:detail, :id=>loc.id end

This works conceptually, but my User model uses betternestedset and would throw an error upon server startup (acts_as_nested_tree not defined), so I tried adding this to routes.rb:

class User < ActiveRecord::Base;end class Location < ActiveRecord::Base;end

Voila! Except for the fact that now, the rest of the app wouldn't work (not exactly sure why...I presume this caused some wonkiness with initialization, but since I'm just re-opening and not re-defining I would think this would still work).

Anyway, so my next idea was to create a routing controller, simply route everything one deep to it, and let it do the lookups and then the appropriate redirect_to. However, I'm afriad of the performance impacts of going this route. It should only add one db lookup and one redirect, but I think the redirect would likely be expensive.

I guess I forward this to the group with hopes that someone has faced this problem before. My questions in order would be:

1. Am I going in the completely wrong direction here? 2. Have any idea why betternestedset is throwing this area? 3. How much overhead do you think to routing controller approach would add. 4. Is there a better way?

Thanks for any help you can provide!

Thanks! Jake

Not sure what problem you're having with 'the rest of the app [not working]' but I have experienced issues when loading classes at startup (environment.rb, initializers, etc) _in development_. The issue relates to the way in which classes are reloaded in dev. Short version is that you end up with weird 'type mismatch' problems even when you've got the correct class. If that's what you're seeing then you can work around it by turning on class_caching in development.rb... as long as you realize you'll have to restart your server for just about any dev change.

If the problem is routing (ie., none of the urls work) then it may be related to the placement of your code in routes.rb. Try pushing it toward the bottom.

Last question, though... is there a really, really compelling reason to use urls like this as opposed to something like http://www.myapp.com/users/JackCutter and http://www.myapp.com/locations/LosAngeles?

The latter are pretty easy to produce. All you have to do is override to_param on the User/Location model. The nice thing is that you can still use the typical named routes. So, for example, the named route to Rome (all routes lead to Rome!):

class Location < ARec::Base   attr_readonly   before_create :dasherize_name

  def to_param     self.dasherized_name   end

  protected   def dasherize_name     self.dasherized_name = self.name.downcase.gsub(/\s+/, '_').dasherize   end end

@rome = Location.find(...) location_path(@rome)

=> .../locations/rome

And in the controller ... def show   @location = Location.find_by_dasherized_name params[:id] end