I’m looking for some feedback on both the philosophy and technical practice of using a top level route that is not a catch-all in Rails.
Example:
# routes.rb
get '/cities' => 'cities#index'
get '/:city_id' => 'cities#show', as: :city, city_id:/([a-z\-\d]+)/
I have about 30k cities that :city_id should be limited to matching things like “/los-angeles” but not “/somewrongthing.jpg”. Since this is the last route, it has become a bit of a catch-all. I am currently rendering a 404 if a city is not found, but this means a hit to the DB each time a missing link comes through. I limited it through constraints, but its not quite the elegant solution I was hoping for.
Are there any solutions besides putting it below something like /city/:city_id?
I think you should be looking at some alternative to handling this in the routes themselves. 30,000 routes would just trade RAM issues for DB issues.
Maybe you have some plain ruby object (file backed, maybe?) that can act as a cities cache and you query it on every request that falls through to your city route.
Something like this, maybe?