Je développe une REST api basée sur Rails. Pour utiliser cette API, vous DEVEZ être connecté. À ce sujet, j'aimerais créer une méthode me
dans mon contrôleur d'utilisateur qui renverra un json des informations de l'utilisateur connecté . Donc, je n'ai pas besoin d'un :id
à transmettre dans l'URL. Je veux juste appeler http://domain.com/api/users/me
Alors j'ai essayé ceci:
namespace :api, defaults: { format: 'json' } do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :tokens, :only => [:create, :destroy]
resources :users, :only => [:index, :update] do
# I tried this
match 'me', :via => :get
# => api_user_me GET /api/users/:user_id/me(.:format) api/v1/users#me {:format=>"json"}
# Then I tried this
member do
get 'me'
end
# => me_api_user GET /api/users/:id/me(.:format) api/v1/users#me {:format=>"json"}
end
end
end
Comme vous pouvez le constater, mon itinéraire attend un identifiant, mais j'aimerais obtenir quelque chose du genre. Quelque chose basé sur current_user
id. Exemple ci-dessous:
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
Dans cet exemple, vous pouvez modifier le mot de passe de l'utilisateur actuel sans passer l'identifiant en tant que paramètre.
Je pourrais utiliser une collection au lieu d'un membre, mais c'est un contournement sale ...
Quelqu'un a une idée? Merci
Les itinéraires de ressources sont conçus pour fonctionner de cette façon. Si vous voulez quelque chose de différent, concevez-le vous-même, comme ceci.
match 'users/me' => 'users#me', :via => :get
Mettez-le en dehors de votre bloc resources :users
Il faut utiliser ressources singulières :
Donc, au lieu de resources
, utilisez resource
:
Parfois, vous avez une ressource que les clients recherchent toujours sans référencer un ID. Par exemple, vous voudriez que/profile affiche toujours le profil de l'utilisateur actuellement connecté. Dans ce cas, vous pouvez utiliser une ressource singulière pour mapper/profile (plutôt que/profile /: id) à l'action show [...]
Donc, dans votre cas:
resource :user do
get :me, on: :member
end
# => me_api_user GET /api/users/me(.:format) api/v1/users#me {:format=>"json"}
Peut-être que je manque quelque chose, mais pourquoi ne pas utiliser:
get 'me', on: :collection
resources :users, only: [:index, :update] do
collection do
get :me, action: 'show'
end
end
spécifier l'action est facultatif. vous pouvez ignorer l'action ici et nommer l'action de votre contrôleur me
.
Vous pouvez utiliser
resources :users, only: [:index, :update] do
get :me, on: :collection
end
ou
resources :users, only: [:index, :update] do
collection do
get :me
end
end
"Un itinéraire de membre nécessite un ID car il agit sur un membre. Un itinéraire de collection ne fonctionne pas car il agit sur une collection d'objets. Preview est un exemple d'itinéraire de membre, car il La recherche est un exemple d’itinéraire de collecte, car elle agit sur (et affiche) une collection d’objets. " (de ici )
Lorsque vous créez une route imbriquée dans une ressource, vous pouvez indiquer s'il s'agit d'une action de membre ou d'une action de collecte.
namespace :api, defaults: { format: 'json' } do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :tokens, :only => [:create, :destroy]
resources :users, :only => [:index, :update] do
# I tried this
match 'me', :via => :get, :collection => true
...
...
Cela donne le même résultat que celui d'Arjan d'une manière plus simple
get 'users/me', to: 'users#me'