Подтвердить что ты не робот

Маршруты Rails: GET без param: id

Я разрабатываю 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

Как вы можете видеть, мой маршрут ждет идентификатора, но я хотел бы получить что-то вроде devise. Что-то основано на current_user id. Пример ниже:

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

В этом примере вы можете редактировать текущий пароль пользователя, не передавая id в качестве параметра.

Я мог бы использовать коллекцию вместо члена, но это грязный обход...

У кого-то есть идея? Спасибо вам

4b9b3361

Ответ 1

Маршруты ресурсов предназначены для работы таким образом. Если вы хотите что-то другое, спроектируйте его самостоятельно, как это.

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

Поместите его вне вашего блока resources :users

Ответ 2

Путь к использованию уникальных ресурсов:

Итак, вместо resources используйте resource:

Иногда у вас есть ресурс, который клиенты всегда ищут без ссылки на ID. Например, вы хотите, чтобы /profile всегда показывал профиль текущего пользователя. В этом случае вы можете использовать особый ресурс для map/profile (а не /profile/: id) для действия show [...]

Итак, в вашем случае:

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

# => me_api_user GET    /api/users/me(.:format)            api/v1/users#me {:format=>"json"}

Ответ 3

Возможно, я что-то упустил, но почему бы вам не использовать:

get 'me', on: :collection

Ответ 4

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

указание действия не является обязательным. вы можете пропустить действие здесь и назовите действие своего контроллера как me.

Ответ 5

Вы можете использовать

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

или

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

"Маршруту участника требуется идентификатор, потому что он действует на члена. Маршрут коллекции не потому, что он действует на коллекцию объектов. Предварительный просмотр - пример маршрута участника, поскольку он действует (и отображает ) один объект. Поиск - пример маршрута коллекции, поскольку он действует (и отображает) коллекцию объектов". (от here)

Ответ 6

Когда вы создаете маршрут, вложенный в ресурс, вы можете указать, является ли это действием члена или действием коллекции.

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

Ответ 7

Это дает тот же результат, что и Arjan более простым способом

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