Question

I have a constrained route that matches usernames like this:

controller :users, :path => '/:username', :as => :user, :constrain => { :username => /^_?[a-z]_?(?:[a-z0-9]_?)*$/i } do
   # lots of nested routes go here
end

When I go to write RSpec tests for this (versus using user_id like normal), all the tests are failing because it "can't find the route" even though it works fine on the server.

describe "for an invalid request" do
  it "should render a 404 if an associated photo is not found" do
    # give it a bad photo id
    xhr :post, :destroy, :id => "999999", :photo_id => "999999", :username => @photo_owner.username
    # not found
    response.status.should == not_found
  end
end

This test was working fine when I was using the user_id in my routes prior to switching to usernames:

resources :users do
  # nested routes
end

and

xhr :post, :destroy, :id => "999999", :photo_id => "999999", :user_id => @photo_owner.id

So what am I doing wrong and what has changed?

My server console shows this which means I should have all of the parameters passed in properly:

Processing by TagsController#destroy as JS
  Parameters: {"constrain"=>{"username"=>/^_?[a-z]_?(?:[a-z0-9]_?)*$/i}, "username"=>"rubynewb", "photo_id"=>"2004-the-title-of-the-photo-here", "id"=>"1797"}
Was it helpful?

Solution

Use :constraints => {...} in your route definition.

You have one too many parameters being passed...

"constrain"=>{"username"=>/^_?[a-z]_?(?:[a-z0-9]_?)*$/i}

Rails doesn't recognize :constrain, therefore it and it's contents are passed along as a parameter instead of being processed by the Rails router.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top