Можно ли отключить стандартный маршрут PUT в Rails 4?
Rails 4 представила PATCH
запросы как метод запроса по умолчанию при выполнении (общих) частичных обновлений объектов. Это соответствует стандартам HTTP, и хороший (более старый) пост, обсуждающий это решение, можно найти здесь:
http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/
Когда вы определяете ресурс в config/routes.rb
, например
resources :books
то по умолчанию в рельсах создаются следующие маршруты:
GET /books books#index
GET /books/:id books#show
POST /books books#create
DELETE /books/:id books#destroy
PATCH /books/:id books#update
PUT /books/:id books#update
Поскольку я разрабатываю новое приложение и не нуждаюсь в обратной совместимости, я хотел бы удалить устаревший маршрут PUT
.
Есть ли простой способ выполнить это в config/routes.rb
?
Объяснение, почему этот трафик PUT
меня беспокоит: Я использую драгоценный камень swagger-docs для автоматического создания документация для моего API. Из-за описанного поведения у меня всегда есть два определения конечных точек для запросов на обновление (PUT
и PATCH
) для каждого ресурса. Плюс, поскольку это потенциально опасный маршрут, я бы хотел, чтобы мой API не поддерживал его с сегодняшнего дня.
ОБНОВЛЕНИЕ из-за первого ответа заголовка в неправильном направлении, я хотел бы уточнить: я не хочу удалять действие 'update', но только устаревший маршрут PUT при сохранении маршрута PATCH.
Ответы
Ответ 1
Чтобы ответить на мой собственный вопрос: нет, в настоящее время невозможно отключить генерацию PUT/PATCH по умолчанию в rails 4, что можно четко увидеть при просмотре источника ActionDispatch:: Routing at https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb и особенно эти строки:
def set_member_mappings_for_resource
member do
get :edit if parent_resource.actions.include?(:edit)
get :show if parent_resource.actions.include?(:show)
if parent_resource.actions.include?(:update)
patch :update
put :update
end
delete :destroy if parent_resource.actions.include?(:destroy)
end
end
Очевидно, что нет (условно) исключения для маршрута PUT
. Я подготовлю вопрос или вытащу запрос на это и вернусь позже с результатом.
До тех пор лучшим решением было бы то, что предложил Хорхе де лос Сантос, хотя это в значительной степени загрязнило бы config/routes.rb
.
Ответ 2
Да, проверьте документы:
http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
resources :photos, except: :update
PATCH и PUT предназначены для разных целей. Пока обновление является частичным, вы должны использовать PATCH, но если вы обновляете все, вы должны использовать PUT.
Это может показаться запутанным, но, допустим, предположим, что вы обновляете связанную модель, это может считаться действием put вместо патча, если вы не изменяете частичную информацию, вы обновляете все отношение.
Также PUT используется для обновления или создания, возможно, соя может быть полезна при добавлении вложенных ресурсов.
http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/
--------------- EDIT с решением:
Чтобы переопределить puts ad:
PATCH 'route', to: 'books#update'
resources :books, except: :update
Rails поймает патч перед ресурсами и отключит put и patch для обновления.
Ссылка:
Переопределить "show" ресурс в Rails
Ответ 3
Спустя пару лет и большая версия Rails позже, похоже, не было никакого прогресса в этой проблеме.
Это помогло мне в верхней части routes.rb
:
Rails.application.routes.draw do
def put(*) end
...
Поскольку метод set_member_mappings_for_resource
, упомянутый в ответе OP, вызывает put
, это просто делает его не-op.
Если вам нужны маршруты put
, вы можете поместить их выше этой строки. Если вы хотите быть фантазией, вы можете определить метод without_verbs(*verbs, &block)
, который временно заменяет различные методы глаголов, дает, а затем возвращает их.
Ответ 4
другое решение для переопределения PATCH следующее:
resources :some_resources do
member { patch action: :event }
end
Это вызовет вызов метода event
в SomeResourceController
, когда мы назовем этот маршрут PATCH /some_resources/:id
или отключить его:
resources :some_resource, except: :update do
member { put action: :update }
end