Mik*_*ike 6 rails-routing ruby-on-rails-4
今天我遇到了一些奇怪的(并且非常不方便)Ruby on Rails行为,即使持续梳理网络也没有产生令人满意的答案.注意:我将方法和路由名称翻译为更容易用英语阅读,并希望我没有引入任何不一致.
Ruby on Rails 4.2.0在Ruby 2.0下执行(也在Ruby 2.2.0下测试)
考虑使用这些操作的控制器,其中包括:
class AssignmentsController < ApplicationController
def update
...
end
def takeover_confirmation
...
end
end
Run Code Online (Sandbox Code Playgroud)
自从我用了很多手工定义路线的,我也没有在routes.rb中使用的资源.有问题的路线定义如下:
...
post 'assignments/:id' => 'assignments#update', as: 'assignment'
post 'assignments/takeover_confirmation' => 'assignments#takeover_confirmation'
...
Run Code Online (Sandbox Code Playgroud)
相关产出rake routes:
assignment POST /assignments/:id(.:format) assignments#update
assignments_takeover_confirmation POST /assignments/takeover_confirmation(.:format) assignments#takeover_confirmation
Run Code Online (Sandbox Code Playgroud)
当我assignments_takeover_confirmation_path对它进行POST时,rails会将其路由到该update方法.服务器日志:
Started POST "/assignments/takeover_confirmation" for ::1 at ...
Processing by AssignmentsController#update as HTML
Run Code Online (Sandbox Code Playgroud)
如果我把update路由定义后的takeover_confirmation一个,它按预期工作(没有检查的支撑柱,update虽然).
此外,写完所有这些之后我发现我update在routes.rb(POST而不是PATCH)中使用了错误的请求类型.在routes.rb中这样做确实解决了我的问题:
patch 'assignments/:id' => 'assignments#update', as: 'assignment'
Run Code Online (Sandbox Code Playgroud)
但是,即使将其定义为POST,Rails也不应该将POST请求指向现有路径"/ assignments/takeover_confirmation"到完全不同的操作,如果它?我担心下次我为同一个控制器使用两个POST路由时,它会再次做同样的事情.
我似乎对Rails路由有一种严重的误解,但不能指责它......
正如katafrakt解释的那样,上面的请求/assignments/takeover_confirmation与路由匹配,assignments/:id因为Rails将"takeover_confirmation"部分解释为字符串并将其用于:id参数.因此,这是完全预期的行为.
为了完整起见,这里有一个工作(如果是简约的)路线定义,它应该受到Chris的评论的启发:
resources :assignments do
collection do
post 'takeover_confirmation'
end
end
Run Code Online (Sandbox Code Playgroud)
在此示例中,仅显式定义了我手动创建的路由.更新,显示等的路由(我最初手动定义)现在由隐式定义resources: :assignments.
相应摘录自rake routes:
...
takeover_confirmation_assignments POST /assignments/takeover_confirmation(.:format) assignments#takeover_confirmation
...
assignment GET /assignments/:id(.:format) assignments#show
PATCH /assignments/:id(.:format) assignments#update
PUT /assignments/:id(.:format) assignments#update
DELETE /assignments/:id(.:format) assignments#destroy
....
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助!
但是,即使将其定义为POST,Rails也不应该将POST请求指向现有路径"/ assignments/takeover_confirmation"到完全不同的操作,如果它?
这应该.Rails路由的匹配顺序与routes.rb文件中定义的顺序完全相同(从上到下).因此,如果它匹配某个规则(并/assignments/takeover_confirmation匹配assignments/:id规则),它将停止处理路由.
这种行为简单而有效.我认为任何一种匹配最佳路线的"智能"都会导致繁琐而意想不到的结果.
BTW这就是为什么catch-all路由曾经在路由文件的最底部定义的原因.
| 归档时间: |
|
| 查看次数: |
2606 次 |
| 最近记录: |