Subdomain based namespacing makes RSpec incorrectly state that the route doesn't exist

Hello,

I’m doing namespace routing based on subdomain, rather than path, so
that http://admin.example.com/pages leads to app/controllers/admin/
pages_controller.rb. Cucumber is following this fine, but RSpec is
complaining that the requested route doesn’t exist even though “rake
routes” shows the route. When I add a standard namespace below the
“scope :admin” block in my routes.rb file, RSpec does recognize the
route, but I don’t want path based namespacing.

The relevant parts of routes.rb, and the spec file follow below, along
with the the RSpec output and the matching line of “rake routes”.

config/routes.rb:

scope :admin, :as => ‘admin’, :module => ‘admin’, :conditions =>
{ :subdomain => ‘admin’ } do
resources :pages
end

spec/controllers/admin/pages_controller_spec.rb:

require ‘spec_helper’
describe Admin::PagesController do
describe “GET index” do
context “while not signed-in” do
it “should redirect to www.example.com” do
get :index
# also tried get :index, :subdomain => ‘admin’
response.should redirect_to(root_url(:subdomain => ‘www’))
end
end
end
end

$ rspec spec/controllers/admin/pages_controller_spec.rb
No DRb server is running. Running in local process instead …
F

Failures:

  1. Admin::PagesController GET index while not signed-in should
    redirect to www.example.com
    Failure/Error: get :index
    ActionController::RoutingError:
    No route matches {:controller=>“admin/pages”}

$ rake routes

admin_pages GET /pages(.:format)
{:action=>“index”, :controller=>“admin/pages”}

Thank you for any help you can offer,

Daniel

On Jun 9, 2011, at 11:03 AM, Daniel wrote:

Hello,

I’m doing namespace routing based on subdomain, rather than path, so
that http://admin.example.com/pages leads to app/controllers/admin/
pages_controller.rb. Cucumber is following this fine, but RSpec is
complaining that the requested route doesn’t exist even though “rake
routes” shows the route.

It’s not that Cucumber gets it wrong and RSpec gets it right. Both tools
delegate to Rails: cucumber-rails scenarios and rspec-rails request
specs to to rails integration tests; rspec-rails controller specs to
rails functional tests.

If you did this in an rspec-rails request spec using the same
declaration you’re using in the cuke scenario, it would pass. If you did
it in a rails functional test it would fail.

More below.

{ :subdomain => ‘admin’ } do
resources :pages
end

The hash key ^^ you’re looking for is :constraints, not :conditions.
Change that and it will work, even in a controller spec. The fact that
it works in a Cucumber scenario is an accident, and likely due to how
the request is being declared in the step definition. If it’s something
like get admin_pages_path, then it’s using rails’ routing to generate
and recognize the path, so it makes sense that it works.

Also, the declaration seems overly complex. You can get what I think
you’re looking for like this:

scope :module => :admin, :constraints => { :subdomain => ‘admin’ } do
resources :pages
end

HTH,

David