是否有可能在Rails 4中禁用标准PUT路由?



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

则在rails 4中默认创建以下路由:

    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 gem为我的API自动生成swagger文档。由于所描述的行为,我总是为每个资源的更新请求定义两个端点(PUTPATCH)。另外,由于这是一个潜在的弃用路由,我希望我的API从今天开始不支持它。


UPDATE由于第一个答案在错误的方向上,我想澄清:我不想删除'更新'动作,但只有过时的PUT路由,同时保持PATCH路由。

回答我自己的问题:不,目前不可能在rails 4中禁用PUT/PATCH组合的默认生成,这可以清楚地看到,当查看ActionDispatch::Routing的源代码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路由的条件。我将为此准备一个问题或拉请求,然后带着结果回来。

在那之前,最好的解决办法是Jorge de los Santos所建议的,尽管这几乎会污染config/routes.rb

是的,检查文档:

http://guides.rubyonrails.org/routing.html restricting-the-routes-created

resources :photos, except: :update

PATCH和PUT有不同的用途。只要更新是局部的,就应该使用PATCH,但如果要更新所有内容,就必须使用PUT。这可能听起来令人困惑,但例如,让我们假设您正在更新关联的模型,这可能被视为放置操作而不是补丁,只要您不修改部分信息,您就更新了整个关系。

PUT也用于更新或创建,您可能会发现它在添加嵌套资源时很有用。

http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/

---------------EDIT with solution:

重写看跌广告:

PATCH 'route', to: 'books#update'
resources :books, except: :update

Rails将在资源之前捕获补丁,并将禁用put和补丁以进行更新。

参考:

覆盖"show"Rails中的资源路由

几年过去了,Rails发布了一个主要版本,但在这个问题上似乎没有任何进展。

这在routes.rb的顶部为我做了这项工作:

Rails.application.routes.draw do
  def put(*) end
  ...

因为在OP的回答中提到的set_member_mappings_for_resource方法调用put,这只是使它成为无操作。

如果你确实需要put路由,你可以把它们放在这条线上。如果您想要更花哨一点,您可以定义一个without_verbs(*verbs, &block)方法,该方法临时替换各种动词方法,产生结果,然后再将它们放回去。

另一个覆盖PATCH的解决方案如下:

resources :some_resources do
  member { patch action: :event }
end

当我们调用路由PATCH /some_resources/:id时,这将导致在SomeResourceController上调用event方法

或禁用:

resources :some_resource, except: :update do
  member { put action: :update }
end

最新更新