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

时间:2014-06-06 12:32:15

标签: ruby-on-rails ruby-on-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

然后在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从今天开始不支持它。


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

4 个答案:

答案 0 :(得分:8)

回答我自己的问题:不,目前无法在rails 4中禁用PUT / PATCH组合的默认生成,这在查看{{3的ActionDispatch :: Routing的来源时可以清楚地看到特别是那些行:

      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

答案 1 :(得分:7)

是的,检查文档:

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/

---------------用解决方案编辑:

要覆盖放置广告:

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

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

参考:

Override "show" resource route in Rails

答案 2 :(得分:2)

几年后,Rails的主要版本以后,在这个问题上似乎没有任何进展。

这在routes.rb的顶部为我完成了工作:

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

由于OP的回答中提到的set_member_mappings_for_resource方法调用了put,因此这只会使其成为无操作。

如果您确实需要put路线,可以将它们放在此行之上。如果你想要花哨,你可以定义一个without_verbs(*verbs, &block)方法,暂时替换各种动词方法,产生,然后将它们放回去。

答案 3 :(得分:0)

覆盖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