Маршрутизация по рельсам: добавьте пользовательский маршрут в стандартный список действий

#ruby-on-rails #rest #routes

Вопрос:

Маршруты Rails создают 7 действий CRUD по умолчанию после REST.

 resources :users
 

Тем не менее, у меня есть confirm_destroy действие, которое я использую почти в каждом ресурсе, потому что у меня много логики, которая отображается на странице подтверждения; это не просто диалоговое окно с предупреждением «да/нет».

 resources :users do
  get :confirm_destroy, on: :member
end
 

С более чем 50 ресурсами становится утомительно записывать это для каждого ресурса, и из-за этого мой файл маршрутов буквально в 3 раза длиннее.

Есть ли какой-либо способ добавить действие в стандарт 7 для resources блока таким образом, чтобы

 resources :users
 

было бы то же самое, что

 resources :users do
  get :confirm_destroy, on: :member
end
 

и я могу использовать его в маршрутах в качестве стандартного действия, т. е.:

 resources :users, only: [:show, :confirm_destroy, :destroy]

resources :users, except: [:confirm_destroy]
 

Комментарии:

1. Взгляните на создание маршрута concern…guides.rubyonrails.org/routing.html#routing-concerns … может быть, ты приблизишься. В противном случае, я думаю, вы войдете в царство исправления обезьян.

2. Я проверил источник и согласен с @dbugger. Нет хорошего крючка, чтобы изменить поведение resources . Исправление обезьян-это всегда вариант, но он хрупок. Опасения-это хорошая идея. Другой вариант-создать свой собственный метод, который вызывает resources ваше действие confirm_destroy

Ответ №1:

Хотя это и не так элегантно, как вам могло бы понравиться, Rails-это способ использовать проблему маршрутизации, как предложил @dbugger.

Например:

 concern :confirmable do
  get 'confirm_destroy', on: :member
end

resources :users, :widgets, concerns: :confirmable
 
 $ rails routes
                                  Prefix Verb   URI Pattern                                                                                       Controller#Action
                    confirm_destroy_user GET    /users/:id/confirm_destroy(.:format)                                                              users#confirm_destroy
                                   users GET    /users(.:format)                                                                                  users#index
                                         POST   /users(.:format)                                                                                  users#create
                                new_user GET    /users/new(.:format)                                                                              users#new
                               edit_user GET    /users/:id/edit(.:format)                                                                         users#edit
                                    user GET    /users/:id(.:format)                                                                              users#show
                                         PATCH  /users/:id(.:format)                                                                              users#update
                                         PUT    /users/:id(.:format)                                                                              users#update
                                         DELETE /users/:id(.:format)                                                                              users#destroy
                  confirm_destroy_widget GET    /widgets/:id/confirm_destroy(.:format)                                                            widgets#confirm_destroy
                                 widgets GET    /widgets(.:format)                                                                                widgets#index
                                         POST   /widgets(.:format)                                                                                widgets#create
                              new_widget GET    /widgets/new(.:format)                                                                            widgets#new
                             edit_widget GET    /widgets/:id/edit(.:format)                                                                       widgets#edit
                                  widget GET    /widgets/:id(.:format)                                                                            widgets#show
                                         PATCH  /widgets/:id(.:format)                                                                            widgets#update
                                         PUT    /widgets/:id(.:format)                                                                            widgets#update
                                         DELETE /widgets/:id(.:format)                                                                            widgets#destroy
 

Комментарии:

1. Работает, как и ожидалось! Уменьшил длину файла моих маршрутов более чем на 100 строк и облегчает его чтение.