Reputation: 2637
So I have a simple users
resource defined in my routes.
resources :users
I need to provide a route so that a logged in user can get his information in the front end. I thought about doing this:
resources :users do
get 'current' , on: :collection
end
But this semantically means that the route gives a list of current users, not the current user. And Indeed if I do rake routes
, it shows the path prefix as: current_users
I can work around the path prefix by doing something like this:
get '/users/current' => 'users#current', as: 'current_user'
But this still looks like it provides a list of users. So, I was wondering if there was a 'right way' to do this kind of thing and how to do it in rails? Or am I thinking too much about this and what I have is fine?
Upvotes: 4
Views: 2263
Reputation: 76774
if there was a 'right way'
The "right" way is to use a singular resource:
#config/routes.rb
resource :user #-> url.com/user -> users#show
Of course, the "right" way implies there is a "wrong" way, which is not the case.
Programming is one of the few practices where you can do whatever you want, so long as the result is achieved. Of course, how you achieve that result can be criticized; ultimately, there are a myriad of ways to achieve it...
#config/routes.rb
resources :users do
get :current, on: :collection #-> url.com/users/current -> users#current
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def current
@user = current_user
end
end
The above (your code) does what my code does, just in a different way.
Just because you're using a collection route, doesn't mean you need to pass a collection. The "collection" route is mainly for Rails routing structures; the routes have no bearing on your backend code.
--
This also means you should be willing to experiment with options / switches to customize your routing:
#config/routes.rb
resource :user, path: "current_user", as: :current_user #-> url.com/current_user -> users#show
Upvotes: 5
Reputation: 1265
Singular Resources as henb noted are what you're looking for. Or this:
get 'user/current' => 'users#current', as :current_user
One thing I've done is use the singular form in the resources statement because the actions dealt with individual users (eg. /usr/573 to display the information for user 573), then added an extra match for the list of all users:
match 'users' => 'user#index', as :user_list, via: [ :get, :post ]
get 'user/current' => 'user#current', as :current_user
resources :user, except: :index
Not precisely RESTful, but it made the URLs reflect accurately whether I was dealing with the set of users vs. an individual user. The :post for the user list is for the search box submission.
Upvotes: 1
Reputation: 577
2.5 Singular Resources Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like /profile to always show the profile of the currently logged in user. In this case, you can use a singular resource to map /profile (rather than /profile/:id) to the show action: http://guides.rubyonrails.org/routing.html#singular-resources
maybe you meant it?
resource :user
Upvotes: 2