web-dev-qa-db-fra.com

Routes Rails: GET sans param: id

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

29
Gozup

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

18
Arjan

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"}
75
Waiting for Dev...

Peut-être que je manque quelque chose, mais pourquoi ne pas utiliser:

get 'me', on: :collection
9
EfratBlaier
  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.

7
manohar

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 )

6
leandrotk

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
...
...
0
manoj

Cela donne le même résultat que celui d'Arjan d'une manière plus simple

get 'users/me', to: 'users#me'

0
Raf