Rails resources are fantastic but the docs can be a little lacking in depth. Unfortunately it’s not exactly clear from the docs how you can create a route like /documents/trash without the show route getting in the way.
I recently found myself in the situation where I wanted to create these two routes:
/documents/trash
/documents/1/
In order to help a user easily restore deleted documents.
My naive implementation was using a member route, take a look:
get '/users/trash' => 'users#trash', as: "users_trash"
resources :users
member do
...
get ':user_id' => 'users#show'
end
resources :user_roles, only: [:new, :destroy, :create]
end
Now this did function but it was in no way the rails way of doing things. Instead after some reading I learned the right way to do this was collection routes:
resources :users do
collection do
get 'trash'
end
member do
...
end
end
Leaving out my irrelevant member routes you can see I’ve added a collection route. Collection routes are routes that belongs to the entire collection of resources not just one member. Member routes are routes that apply an action to a specific member of the resource.
So next time you need a route inside a resource don’t use a one-off use a collection route.