【问题标题】:RSpec controller example param with periods带有句点的 RSpec 控制器示例参数
【发布时间】:2012-10-05 18:55:38
【问题描述】:

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

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

【问题讨论】:

    标签: ruby-on-rails rspec


    【解决方案1】:

    您遇到两个问题: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 中添加此约束的其他方法的大量重要信息

    【讨论】:

    • 我将约束添加到了我的 routes.rb 文件中,但这似乎没有帮助,在应用约束之前,rails 的某些部分会拦截它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多