aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorSimon Courtois <scourtois_github@cubyx.fr>2018-09-27 19:51:57 +0200
committerRafael Mendonça França <rafaelmfranca@gmail.com>2018-09-27 16:35:55 -0400
commitd043920eb903d32a1e3540690d3b08d98d1b6d88 (patch)
tree647b6e3b4ac25e3ecd88b149fa8efbf96c811f46 /actionpack
parentd0d1cd3d45f14e8423ee8ee3f4c19e999a69b96c (diff)
downloadrails-d043920eb903d32a1e3540690d3b08d98d1b6d88.tar.gz
rails-d043920eb903d32a1e3540690d3b08d98d1b6d88.tar.bz2
rails-d043920eb903d32a1e3540690d3b08d98d1b6d88.zip
Fixing an edge case when using objects as constraints
This PR fixes an issue when the following situation occurs. If you define a class like this class MyConstraint def call(*args) # for some reason this is defined end def matches?(*args) # checking the args end end and try to use it as a constraint get "/", to: "home#show", constraints: MyConstraint.new if its `matches?` method returns `false` there will be an error for the mapper will ask for the constraint arity, thinking it is a proc, lambda or method. This PR checks for the presence of the `arity` method on the constraint calling it only if present, preventing the error while keeping the basic behavior.
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb14
-rw-r--r--actionpack/test/dispatch/routing_test.rb15
2 files changed, 28 insertions, 1 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index b618b9c400..8386cb9689 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -50,7 +50,19 @@ module ActionDispatch
private
def constraint_args(constraint, request)
- constraint.arity == 1 ? [request] : [request.path_parameters, request]
+ arity = if constraint.respond_to?(:arity)
+ constraint.arity
+ else
+ constraint.method(:call).arity
+ end
+
+ if arity < 1
+ []
+ elsif arity == 1
+ [request]
+ else
+ [request.path_parameters, request]
+ end
end
end
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 5efbe5b553..ee87791538 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -115,6 +115,21 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal 301, status
end
+ def test_accepts_a_constraint_object_responding_to_call
+ constraint = Class.new do
+ def call(*); true; end
+ def matches?(*); false; end
+ end
+
+ draw do
+ get "/", to: "home#show", constraints: constraint.new
+ end
+
+ assert_nothing_raised do
+ get "/"
+ end
+ end
+
def test_namespace_with_controller_segment
assert_raise(ArgumentError) do
draw do