46

我正在开发一个基于 rails 的 REST api。要使用此 api,您必须登录。关于这一点,我想me在我的用户控制器中创建一个方法,该方法将返回登录用户信息的 json。所以,我不需要:id在 URL 中传递。我只想打电话给http://domain.com/api/users/me

所以我尝试了这个:

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

如您所见,我的路线等待一个 id,但我想得到类似设计的东西。基于current_userid 的东西。下面的例子:

edit_user_password GET    /users/password/edit(.:format)         devise/passwords#edit

在此示例中,您可以编辑当前用户密码,而无需将 id 作为参数传递。

我可以使用集合而不是成员,但这是一个肮脏的绕过......

有人有想法吗?谢谢

4

7 回答 7

116

要走的路是使用单一资源

所以,而不是resources使用resource

有时,您有一个资源,客户端总是在不引用 ID 的情况下查找该资源。例如,您希望 /profile 始终显示当前登录用户的个人资料。在这种情况下,您可以使用单一资源将 /profile(而不是 /profile/:id)映射到显示操作 [...]

所以,在你的情况下:

resource :user do
  get :me, on: :member
end

# => me_api_user GET    /api/users/me(.:format)            api/v1/users#me {:format=>"json"}
于 2014-09-03T10:38:38.383 回答
24

资源路由旨在以这种方式工作。如果您想要不同的东西,请自己设计,就像这样。

match 'users/me' => 'users#me', :via => :get

把它放在你的resources :users街区之外

于 2013-06-12T13:29:33.117 回答
19

您可以使用

resources :users, only: [:index, :update] do
  get :me, on: :collection
end

或者

resources :users, only: [:index, :update] do
  collection do
    get :me
  end
end

“成员路由需要 ID,因为它作用于成员。集合路由不需要,因为它作用于对象集合。预览是成员路由的一个示例,因为它作用于(并显示)单个对象。搜索是集合路径的一个示例,因为它作用于(并显示)对象集合。” (从这里

于 2015-10-09T14:49:24.083 回答
13

也许我错过了一些东西,但你为什么不使用:

get 'me', on: :collection
于 2013-06-12T13:28:16.150 回答
7
  resources :users, only: [:index, :update] do
    collection do
      get :me, action: 'show' 
    end
  end

指定动作是可选的。您可以在此处跳过操作并将您的控制器操作命名为me.

于 2015-09-22T10:58:53.347 回答
3

这以更简单的方式给出了与 Arjan 相同的结果

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

于 2017-06-14T15:00:02.257 回答
0

当您创建嵌套在资源中的路由时,您可以提及它是成员操作还是集合操作。

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
...
...
于 2013-06-12T13:29:07.093 回答