Reputation: 6603
Using rails --api
, expected rails to route as PUT
method from POST and params[:_method]='put'
, but is routing as POST
Consider the following:
config/routes.rb:
resources :sessions, do
put 'authenticate', on: :collection
end
some client HTML file:
<form action='http://localhost:3000/sessions/authenticate' method='post'>
<input type='hidden' name='_method' value='put'>
...
</form>
...upon form submit:
rails server
output:
Started POST "/sessions/authenticate" for ::1 at 2018-03-07 11:20:21 +0000
No route matches [POST] "/sessions/authenticate" excluded from capture: DSN not set
ActionController::RoutingError (No route matches [POST] "/sessions/authenticate"):
actionpack (4.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
actionpack (4.2.8) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
...
Inspecting Chrome -> Developer Tools -> Network tab -> [REQUEST], the payload is correct as shown below:
General
Request URL:http://localhost:3000/sessions/authenticate
...FormData
_method:put
...
--api
mode, and the request worked: that it recognised the _method='PUT'
and route as a PUT
properly. So, I have a feeling that this just got to do with some differences between normal rails and the api mode. Unfortunately, after several searches I couldn't find any solution.Any help would be appreciated.
Upvotes: 4
Views: 2001
Reputation: 230461
Handling of _method
hidden fields is done by a piece of rack middleware.
http://guides.rubyonrails.org/configuring.html#configuring-middleware
Rack::MethodOverride allows the method to be overridden if
params[:_method]
is set. This is the middleware which supports the PATCH, PUT, and DELETE HTTP method types.
I'm guessing you don't have that in api mode. Add it and the request should be routed correctly.
I didn't know this myself (or forgot a long time ago). Here's how I found out.
:_method
(as this is likely how rails would address the field). After two minutes realize that github doesn't search the exact term.Grep the local codebase (0.5 seconds)
sergio@soviet-russia ‹ master › : ~/projects/github/rails
[0] % ag ":_method"
guides/source/rails_on_rack.md
238:* Allows the method to be overridden if `params[:_method]` is set. This is the middleware which supports the PUT and DELETE HTTP method types.
guides/source/configuring.md
235:* `Rack::MethodOverride` allows the method to be overridden if `params[:_method]` is set. This is the middleware which supports the PATCH, PUT, and DELETE HTTP method types.
Total time taken: ~7 minutes. Rails itself actually didn't contain actual relevant code, but it had the docs. I got lucky. :)
Upvotes: 6