Where is the code that actually translates _method value for put and delete requests

If you have developed RESTful application then you know that for update and delete method PUT and DELETE is used. Since current browsers do not support method ‘put’ and ‘delete’, Rails puts a hiddent variable called _method. That’s all good.

In the action_controller Rails checks if the method is ‘put’ or ‘delete’. end

 
# actionpack/lib/action_controller/request.rb
def get?
  method  :get
end

def post?
  request_method  :post

def put?
  request_method  :put
end

def delete?
  request_method  :delete
end

Objective

Where is the code that translates _method into method = ‘put’ or method = ‘delete’.

The code that makes use of _method is not inside Rails. It is packaged as a gem called ‘rack’. If you want to look at the code base of this gem then create a Rails 2.3 application and then unpack gem like this.

 
rails demo
cd demo
rake rails:freeze:gems

Now go to vendor/rails/actionpack/actioncontroller/vendor/rack/methodoverride.rb . There you will see code like this

 
module Rack
  class MethodOverride
    HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS)

    METHOD_OVERRIDE_PARAM_KEY = "_method".freeze
    HTTP_METHOD_OVERRIDE_HEADER = "HTTP_X_HTTP_METHOD_OVERRIDE".freeze

    def initialize(app)
      @app = app
    end

    def call(env)
      if env["REQUEST_METHOD"] == "POST" 
        req = Request.new(env)
        method = req.POST[METHOD_OVERRIDE_PARAM_KEY] ||
          env[HTTP_METHOD_OVERRIDE_HEADER]
        method = method.to_s.upcase
        if HTTP_METHODS.include?(method)
          env["rack.methodoverride.original_method"] = env["REQUEST_METHOD"]
          env["REQUEST_METHOD"] = method
        end
      end

      @app.call(env)
    end
  end
end

As you can see above if the request method is POST and if there is value for params ’_method’ then request method is set to ‘put’ or ‘delete’.

As I said this functionality is not directly coded in Rails. This functionality is distributed as rack module which means Sinatra and other ruby frameworks can make use of this feature. When you installed Rails 2.3 then rack gem also gets installed. To see the listing of this gem do this

 
> gem list rack

*** LOCAL GEMS ***

rack (1.0.0, 0.4.0)

Post a new comment




Wrap code in <pre> ... </pre>

My name is Neeraj. You can contact me at neerajdotname@gmail.com . I am also on twitter , facebook and Linkedin .

admin_data , active_record_no_table , session_expiration_management , always_at_bottom and javascript_lab are some of my projects on github .