recognize_path skips scoped params in constraints #4260

Closed
ybart opened this Issue Jan 2, 2012 · 6 comments

Projects

None yet

4 participants

@ybart
ybart commented Jan 2, 2012

Using Rails 3.1 and 3.2.0.rc1, using recognize_path causes params not being provided to route constraints.

While the route works correctly when called directly (using a browser, or via app.get), it fails being recognized using recognized_path.

Here is the route:

scope '/prefix/:scoped_param/suffix' do
  constraints(ParamConstraint.new) do
    resource :success
  end
end

Here is the constraint

class ParamConstraint
  def matches?(request)
    Rails.logger.info request.params
    return request.params[:scoped_param]
  end
end

Here are the tests

class ScopedParamConstraintTest < ActionDispatch::IntegrationTest
  test "Can fetch scoped page" do
    get helper.success_path(scoped_param: 'test')
    assert_response :success
  end

  test "Can recognize scoped page path" do
    assert_not_nil Rails.application.routes.recognize_path(helper.success_path(scoped_param: 'test'))
  end
end

Test results

# Running tests:

.E

Finished tests in 0.092361s, 21.6542 tests/s, 10.8271 assertions/s.

  1) Error:
test_Can_recognize_scoped_page_path(ScopedParamConstraintTest):
ActionController::RoutingError: No route matches "/prefix/test/suffix/success"
    /Users/ybart/.rvm/gems/ruby-1.9.3-p0/gems/actionpack-3.2.0.rc1/lib/action_dispatch/routing/route_set.rb:603:in `recognize_path'
    /Users/ybart/Documents/sources/tests/rails/scoped-param-constraint/test/integration/scoped_param_constraint_test.rb:10:in `block in <class:ScopedParamConstraintTest>'

2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
Errors running test:integration! #<RuntimeError: Command failed with status (1): [/Users/ybart/.rvm/rubies/ruby-1.9.3-p0/bin...]>

I can provide a test project if needed.

@tenderlove
Member

Yes, please provide a test project. Thanks.

@tenderlove tenderlove was assigned Jan 3, 2012
@ybart
ybart commented Jan 4, 2012

Here it is !

git clone git://github.com/ybart/rails_scoped-param-constraint_test.git && cd rails_scoped-param-constraint_test && bundle && rake
@ybart
ybart commented Jan 27, 2012

Still occurring in Rails 3.2.1.

@KL-7
Contributor
KL-7 commented Jan 28, 2012

@ybart, according to the docs you should pass class but not an instance to constraints method. If you change your routes like that:

scope '/prefix/:scoped_param/suffix' do
  constraints(ParamConstraint) do
    resource :success
  end
end

it successfully passes all these tests:

test "Can fetch scoped page" do
  get helper.success_path(scoped_param: 'test')
  assert_response :success
end

test "Can't fetch unscoped page" do
  assert_raise ActionController::RoutingError do
    get helper.success_path
  end
end

test "Can recognize scoped page path" do
  assert_recognizes(
      { :controller => 'successes', :action => 'show', :scoped_param => 'test' }, 
      helper.success_path(scoped_param: 'test')
  )
end
@ybart ybart closed this Jan 30, 2012
@ybart
ybart commented Jan 30, 2012

@KL-7 Thanks for pointing this. I just confirmed my code is working with this modification. Despite my code worked in 3.0.x, the problem resides in my code, not in Rails.

@JeffreyLeeSpokeo JeffreyLeeSpokeo added a commit to JeffreyLeeSpokeo/rails that referenced this issue Mar 4, 2015
@JeffreyLeeSpokeo JeffreyLeeSpokeo Fix for ticket #4260. Where a constraint was not reading any request …
…parameters. I passed into constraint.matches? the parameters generated in routing mapper. Included in the pull request is an appropriate unit test.
0256e88
@JeffreyLeeSpokeo

So making a note that recognize_path still doesn't work with rails 3.2 when there are constraints in the routes. However, if you do run into this bug, note that it works on 4.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment