diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 1bbb4f1..e759e36 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -23,16 +23,14 @@ module ActionDispatch def call(env) req = @request.new(env) + matches?(req) ? @app.call(env) : [ 404, {'X-Cascade' => 'pass'}, [] ] + end - @constraints.each { |constraint| - if constraint.respond_to?(:matches?) && !constraint.matches?(req) - return [ 404, {'X-Cascade' => 'pass'}, [] ] - elsif constraint.respond_to?(:call) && !constraint.call(*constraint_args(constraint, req)) - return [ 404, {'X-Cascade' => 'pass'}, [] ] - end - } - - @app.call(env) + def matches?(req) + @constraints.all? do |constraint| + (constraint.respond_to?(:matches?) && constraint.matches?(req)) || + (constraint.respond_to?(:call) && constraint.call(*constraint_args(constraint, req))) + end end private diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 32f4193..e8625bd 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -550,7 +550,9 @@ module ActionDispatch end dispatcher = route.app - dispatcher = dispatcher.app while dispatcher.is_a?(Mapper::Constraints) + while dispatcher.is_a?(Mapper::Constraints) + dispatcher = dispatcher.matches?(req) ? dispatcher.app : nil + end if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, false) dispatcher.prepare_params!(params) diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 0ac8c24..2ab0fe7 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -80,6 +80,11 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest match "/projects/status(.:format)" + constraints(lambda {|req| false }) do + get 'terms' => "terms#special" + end + get 'terms' => "terms#default" + constraints(:ip => /192\.168\.1\.\d\d\d/) do get 'admin' => "queenbee#index" end @@ -1447,6 +1452,13 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_assert_recognizes_with_constraints + with_test_routes do + @routes = Routes + assert_recognizes({:controller => "terms", :action => "default"}, "/terms") + end + end + def test_resource_new_actions with_test_routes do assert_equal '/replies/new/preview', preview_new_reply_path