I currently have the following routes set up for photos
:
resources :photos
match 'photos/:user' => 'photos#user', :as => :user_photo
match 'photos/:user/:key' => 'photos#show', :as => :show_photo
Those two match
routes give me URLs like:
http://example.com/photos/joe_schmoe
http://example.com/photos/joe_schmoe/123xyz
...similar to the way Flickr formats its URLs.
The problem I'm having, though, is that the photos/:user
route is either interpreted as the show
method, or if I put those custom routes before the resources
then routes like /new
get interpreted as the user
method.
How can I get around that without having to do a ton of custom routes?
You'll want to put this custom route above the resources :users
, so that it is matched first in the routes.
match 'photos/:user' => 'photos#user', :as => :user_photo
resources :photos
Additionally you can disable the show
action altogether:
resources :photos, :except => :show
It's not a good idea to mix restful routes with custom match routes on the same resource. As you observed these two routes will intercept each others actions. Your best choice is to pick only one routing system for a resource and stick with it. If you want flickr style routes you should remove the restful route and add the other necessary match routes for new/create/etc you might need. If you desperately want to keep both of these routes You either need to disable show from the rest route with the rest route being on top, or you disable new from the match route while match being on top. You can use regexp to filter out some requests from match like this:
match 'photos/:user' => 'photos#user', :as => :user_photo, :constraints => { :user => /.*[^n][^e][^w].*/ }
This gets ugly really fast tho and I suggest just not using the rest route at all.