TLDR:
使用rails --api
,期望轨道作为PUT
方法从POST and params[:_method]='put'
路由,但路由为POST
鉴于:
- 导轨 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 -> 开发者工具 -> 网络选项卡 -> [请求],有效负载正确,如下所示:
一般请求 URL:http://
localhost:3000/sessions/authenticate
...FormData
_method:put
...
故障 排除
- 我尝试在一个新的 rails 项目中复制确切的代码,但这次没有使用
--api
模式,并且请求有效:它正确地将_method='PUT'
和路由识别为PUT
。所以,我有一种感觉,这与普通轨道和 api 模式之间的一些差异有关。不幸的是,经过几次搜索,我找不到任何解决方案。
任何帮助将不胜感激。
_method
隐藏字段的处理由机架中间件完成。
http://guides.rubyonrails.org/configuring.html#configuring-middleware
Rack::MethodOverride允许在设置
params[:_method]
时覆盖该方法。这是支持 PATCH、PUT 和 DELETE HTTP 方法类型的中间件。
我猜你在 api 模式下没有它。添加它,请求应正确路由。
奖金曲目
我自己不知道(或者很久以前就忘记了)。这是我是如何发现的。
- 转到 https://github.com/rails/rails 并尝试在该存储库中搜索
:_method
(因为这可能是 rails 处理该字段的方式)。两分钟后,意识到github不会搜索确切的术语。 - 本地克隆轨道存储库(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本身实际上不包含实际的相关代码,但它有文档。我很幸运。:)