Rails 3 routes: How to avoid conflict with 'sh

2019-07-01 11:03发布

问题:

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?

回答1:

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


回答2:

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.