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
给定:
- rails 4.2.8
- rails-api 0.4.1
考虑以下因素:
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
...
疑难解答
- 我尝试在新的 rails 项目中复制确切的代码,但这次没有使用
--api
模式,并且请求有效:它识别了 _method='PUT'
和路由作为 PUT
正确。所以,我觉得这与正常 rails 和 api 模式之间的一些差异有关。不幸的是,经过多次搜索我找不到任何解决方案。
如有任何帮助,我们将不胜感激。
_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 模式下没有那个。添加它,请求应该被正确路由。
奖励曲目
我自己并不知道(或者很久以前就忘记了)。这是我的发现。
- 转到 https://github.com/rails/rails 并尝试在该存储库中搜索
:_method
(因为这很可能是 rails 处理该字段的方式)。两分钟后发现 github 没有搜索确切的字词。
- 在本地克隆 rails 存储库(5 分钟)
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 本身实际上并不包含实际的相关代码,但它有文档。我很幸运。 :)
TLDR:
使用 rails --api
,预期 rails 从 POST and params[:_method]='put'
路由为 PUT
方法,但路由为 POST
给定:
- rails 4.2.8
- rails-api 0.4.1
考虑以下因素:
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
...
疑难解答
- 我尝试在新的 rails 项目中复制确切的代码,但这次没有使用
--api
模式,并且请求有效:它识别了_method='PUT'
和路由作为PUT
正确。所以,我觉得这与正常 rails 和 api 模式之间的一些差异有关。不幸的是,经过多次搜索我找不到任何解决方案。
如有任何帮助,我们将不胜感激。
_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 模式下没有那个。添加它,请求应该被正确路由。
奖励曲目
我自己并不知道(或者很久以前就忘记了)。这是我的发现。
- 转到 https://github.com/rails/rails 并尝试在该存储库中搜索
:_method
(因为这很可能是 rails 处理该字段的方式)。两分钟后发现 github 没有搜索确切的字词。 - 在本地克隆 rails 存储库(5 分钟)
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 本身实际上并不包含实际的相关代码,但它有文档。我很幸运。 :)