Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to disable the standard PUT route in Rails 4?

Rails 4 has introduced PATCH requests to be the default request method when doing the (common) partial updates on objects. This is conformal to HTTP standards and a good (older) post discussing this decision can be found here:

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

When you define a resource in config/routes.rb like

    resources :books

then the following routes are created per default in 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

As I am developing a new application and do not have to care about backwards compatibility, I would like to remove the obsolete PUT route.

Is there an easy way for accomplishing this in config/routes.rb?


Explanation why this PUT route bothers me: I am using the swagger-docs gem for automatically generating a swagger documentation for my API. Due to the described behavior, I always have two endpoint definitions for update requests (PUT and PATCH) for every resource. Plus as this is a potentially deprecating route, I would like my API to not support it from today on.


UPDATE due to the first answers heading in the wrong direction I would like to clarify: I do not want to remove the 'update' action, but only the obsolete PUT route while keeping the PATCH route.

like image 271
Peter Sorowka Avatar asked Jun 06 '14 12:06

Peter Sorowka


People also ask

What is RESTful route in Rails?

In Rails, a RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database. A single entry in the routing file, such as. map.resources :photos. creates seven different routes in your application: HTTP verb.

What is the difference between resource and resources in Rails?

Difference between singular resource and resources in Rails routes. So far, we have been using resources to declare a resource. Rails also lets us declare a singular version of it using resource. Rails recommends us to use singular resource when we do not have an identifier.

How do I see all routes in Rails?

Decoding the http request TIP: If you ever want to list all the routes of your application you can use rails routes on your terminal and if you want to list routes of a specific resource, you can use rails routes | grep hotel . This will list all the routes of Hotel.


3 Answers

To answer my own question: no, it is currently not possible to disable the default generation of the PUT/PATCH combination in rails 4, which can be clearly seen when looking at the source of ActionDispatch::Routing at https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb and especially those lines:

      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

Obviously, there is (currently) no conditional for excluding the PUT route. I will prepare an issue or pull request for this and come back later with the result of that.

Until then, the best workaround would be what Jorge de los Santos has suggested, although this would pretty much pollute config/routes.rb.

like image 73
Peter Sorowka Avatar answered Sep 19 '22 16:09

Peter Sorowka


Yes it is, check the docs:

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

resources :photos, except: :update

PATCH and PUT are meant for different uses. As long as the update is partial you should be using PATCH but if you are updating everything you must use PUT. This can sound confusing, but for example let's suppose you are updating the associated model, this might be considered a put action instead of a patch as long as you are not modifying a partial info, you are update the whole relation.

Also PUT is used to update or create, soy might be found it useful when adding nested resources.

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

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

To override puts ad:

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

Rails will catch the patch before the resources and will disable the put and patch for update.

Reference:

Override "show" resource route in Rails

like image 30
Jorge de los Santos Avatar answered Sep 21 '22 16:09

Jorge de los Santos


A couple of years and a major version of Rails later, there doesn't seem to be any progress on this issue.

This did the job for me at the top of routes.rb:

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

Because the set_member_mappings_for_resource method mentioned in the OP's answer calls put, this simply makes it a no-op.

If you do need put routes, you could put them above this line. If you wanted to be fancy, you could define a without_verbs(*verbs, &block) method that temporarily replaces the various verb methods, yields, and then puts them back.

like image 39
Neil E. Pearson Avatar answered Sep 17 '22 16:09

Neil E. Pearson