RSpec 3.1升级:命名空间路由不再被识别

时间:2015-01-08 12:42:53

标签: ruby-on-rails ruby-on-rails-3 rspec rails-routing

从Rails 3.0升级到3.2.21,RSpec从2.14升级到3.1后,我的API路由(命名空间,见下文)不再起作用了。具体来说,它们出现在rake routes中并在开发模式下在浏览器中工作,但它们导致"未找到路由"测试中的异常,我无法在控制台中识别它们(但这可能是我的无知......任何帮助表示赞赏)。

其他(非命名空间)路由可以正常工作。

以下是路线定义:

namespace :api, path: '', defaults: { format: :json }, constraints: { format: :json, subdomain: 'api' } do
  namespace :v1 do
    resources :foos, only: [:index] do
      post :bar, on: :collection
    end
  end
end
match '*path' => 'application#route_not_found'   # default 404 route

以下是rake routes输出:

bar_api_v1_foo_index POST   /v1/foo/bar(.:format) api/v1/foo#bar {:format=>:json, :subdomain=>"api"}
          api_v1_foo DELETE /v1/foo/:id(.:format) api/v1/foo#destroy {:format=>:json, :subdomain=>"api"}

这是我的规范(在spec/integration/api_v1_foo_controller_spec.rb中):

require "spec_helper"
describe Api::V1::FooController do
  before do
    host! "api.#{host}"     # set subdomain, see http://elia.schito.me/2011/09/15/set-subdomain-in-rails-3-request-specs/
  end
  describe "POST" do
    it "should bar" do
      post "/v1/foo/bar"
    end
  end
end

这是规格输出:

故障:

1) Api::V1::FooController POST should bar
   Failure/Error: post "/v1/foo/bar"
   ActionController::RoutingError:
     No route matches [POST] "/v1/foo/bar"
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-3.2.21/lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-3.2.21/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'

我在控制台中使用路由工作的微弱尝试也失败了,但对于所有Rails版本。它可能是语法(你如何使用它?)。

Rails.application.routes.recognize_path '/v1/foo/bar', method: :post, subdomain: 'api', format: :json
=> {:controller=>"application", :action=>"route_not_found", :path=>"v1/foo/bar"}

为什么上面的测试在升级到Rails 3.2和Rspec 3.1之后失败了?

更新

这可能是RoR错误的影响:https://github.com/rails/rails/issues/8679

如果我删除路由定义的subdomain: 'api'块内的constraints,则所有Rails 3.2.21,4.1.9和4-2-stable都将接受路由并工作。如果我强制规范是请求规范并且host! "api.#{host}"更改为host! "api.example.com",则路由也可以。

这是故意的吗?是否有另一种方法可以限制到特定子域的路由?

0 个答案:

没有答案