PUT 或 PATCH `_method` 参数在 rails-api 中不起作用或不受尊重

PUT or PATCH `_method` param not working or not being respected in rails-api

TLDR:

使用 rails --api,预期 rails 从 POST and params[:_method]='put' 路由为 PUT 方法,但路由为 POST

给定:

考虑以下因素:

config/routes.rb:

resources :sessions, do
  put 'authenticate', on: :collection
end

一些客户HTML文件:

<form action='http://localhost:3000/sessions/authenticate' method='post'>
  <input type='hidden' name='_method' value='put'>
  ...
</form>

...表单提交后:

rails server 输出:

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'
  ...

检查Chrome -> Developer Tools -> Network tab -> [REQUEST],payload正确如下:

General
Request URL:http://localhost:3000/sessions/authenticate
...

FormData
_method:put
...

疑难解答

如有任何帮助,我们将不胜感激。

_method 隐藏字段的处理由一个机架中间件完成。

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.

我猜你在 api 模式下没有那个。添加它,请求应该被正确路由。

奖励曲目

我自己并不知道(或者很久以前就忘记了)。这是我的发现。

  1. 转到 https://github.com/rails/rails 并尝试在该存储库中搜索 :_method(因为这很可能是 rails 处理该字段的方式)。两分钟后发现 github 没有搜索确切的字词。
  2. 在本地克隆 rails 存储库(5 分钟)
  3. Grep 本地代码库(0.5 秒)

    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.
    

总耗时:~7 分钟。 Rails 本身实际上并不包含实际的相关代码,但它有文档。我很幸运。 :)