2

在我的控制器规范中,当我执行该行时:

  post :register_pass, :device_id => 'DEV1C3', :pass_type_id => 'pass.com.example.GSPassType', :serial_no => '5ER14L'

我得到一个ActionController::RoutingError

  Failure/Error: post :register_pass, :device_id => 'DEV1C3', :pass_type_id => 'pass.com.example.GSPassType', :serial_no => '5ER14L'
  ActionController::RoutingError:
   No route matches {:action=>"register_pass", :controller=>"purchases/passbook/registrations", :pass_type_id=>"pass.com.example.GSPassType", :serial_no=>"5ER14L", :device_id=>"DEV1C3"}

即使rake routes | grep register_pass退货

register_pass POST   /v1/devices/:device_id/registrations/:pass_type_id/:serial_no(.:format)        {:action=>"register_pass", :controller=>"purchases/passbook/registrations"}

但是,当我删除:pass_type_id值中的句点时,post上面列出的行会执行并且路由被识别(我使用 rspec 验证了这一点,甚至直接卷曲它,在预期的控制器操作中放置一个断点,路由工作)。

我尝试使用Rack::Utils.escape带句点的值,但这也失败了。我还尝试手动将句点更改为它们的 URL 编码值,但 rails 似乎没有在 params 哈希中解码它们。

为什么在这种情况下经期不起作用?

以及如何获得一个传入句点的值(无需String#gsub在控制器中使用手动解码?

4

1 回答 1

2

您遇到了两个问题:1)句点是 URL 序列中的有效字符,因此不会被Rack::Utils.escapeor替换URI.escape,2)Rails 将句点视为路径分隔符以在末尾启用格式解析url,例如 .json、.xml 等(定义见ActionController::Routing::SEPARATORS)。

对于这个用例,我建议向这条路线添加约束,允许您允许:post_id. 我看不到您的路由文件是什么样的,但随着更改可能是这样的:

post "/v1/devices/:device_id/registrations/:pass_type_id/:serial_no(.:format)" => 
  "purchases/passbook/registrations#register_pass", 
  :constraints => { :pass_type_id => /.*/ }

在Rails 路由指南中添加了有关添加此约束的其他方法的大量重要信息

于 2012-10-05T23:12:44.817 回答