2012-10-05 77 views
2

在我的控制器的规格,RSpec的控制器例如PARAM当我执行这一行:与周期

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手动解码它

回答

2

有你遇到两个问题:1)的期间为在URL中有效的字符序列,所以它不会被Rack::Utils.escapeURI.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 guide on routing

+0

我添加了添加此约束约束我的routes.rb文件,但这似乎没有帮助,是轨道拦截的一部分应用约束之前? – tlehman

+0

你必须告诉我你是如何添加约束的。 – rossta

+0

这是一个错字,你是绝对正确的。 – tlehman