Skip to content
Browse files

Merge pull request #9437 from senny/9432_undefined_method_source_in_r…

…outes

the router allows String contraints.
  • Loading branch information...
2 parents ffeb7dd + 09d9f04 commit 923ec86f04ea9c55e646cba1d0d588d033252d17 @pixeltrix pixeltrix committed Feb 26, 2013
View
10 actionpack/CHANGELOG.md
@@ -1,10 +1,18 @@
## Rails 4.0.0 (unreleased) ##
+* Don't verify Regexp requirements for non-Regexp `:constraints`.
+ Fixes #9432.
+
+ Example:
+
+ get '/photos.:format' => 'feeds#photos', constraints: {format: 'xml'}
+
+ *Yves Senn*
+
* Make `ActionDispatch::Journey::Path::Pattern#new` raise more meaningful exception message.
*Thierry Zires*
-
## Rails 4.0.0.beta1 (February 25, 2013) ##
* Fix `respond_to` not using formats that have no block if all is present. *Michael Grosser*
View
28 actionpack/lib/action_dispatch/routing/mapper.rb
@@ -124,15 +124,7 @@ def normalize_format!
def normalize_requirements!
constraints.each do |key, requirement|
next unless segment_keys.include?(key) || key == :controller
-
- if requirement.source =~ ANCHOR_CHARACTERS_REGEX
- raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
- end
-
- if requirement.multiline?
- raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}"
- end
-
+ verify_regexp_requirement(requirement) if requirement.is_a?(Regexp)
@requirements[key] = requirement
end
@@ -145,6 +137,16 @@ def normalize_requirements!
end
end
+ def verify_regexp_requirement(requirement)
+ if requirement.source =~ ANCHOR_CHARACTERS_REGEX
+ raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
+ end
+
+ if requirement.multiline?
+ raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}"
+ end
+ end
+
def normalize_defaults!
@defaults.merge!(scope[:defaults]) if scope[:defaults]
@defaults.merge!(options[:defaults]) if options[:defaults]
@@ -425,11 +427,15 @@ def root(options = {})
# end
#
# [:constraints]
- # Constrains parameters with a hash of regular expressions or an
- # object that responds to <tt>matches?</tt>
+ # Constrains parameters with a hash of regular expressions
+ # or an object that responds to <tt>matches?</tt>. In addition, constraints
+ # other than path can also be specified with any object
+ # that responds to <tt>===</tt> (eg. String, Array, Range, etc.).
#
# match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }
#
+ # match 'json_only', constraints: { format: 'json' }
+ #
# class Blacklist
# def matches?(request) request.remote_ip == '1.2.3.4' end
# end
View
36 actionpack/test/dispatch/routing_test.rb
@@ -3380,6 +3380,42 @@ def test_regexp_port_constraints
end
end
+class TestFormatConstraints < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+
+ get '/string', to: ok, constraints: { format: 'json' }
+ get '/regexp', to: ok, constraints: { format: /json/ }
+ end
+ end
+
+ include Routes.url_helpers
+ def app; Routes end
+
+ def test_string_format_constraints
+ get 'http://www.example.com/string'
+ assert_response :success
+
+ get 'http://www.example.com/string.json'
+ assert_response :success
+
+ get 'http://www.example.com/string.html'
+ assert_response :not_found
+ end
+
+ def test_regexp_format_constraints
+ get 'http://www.example.com/regexp'
+ assert_response :success
+
+ get 'http://www.example.com/regexp.json'
+ assert_response :success
+
+ get 'http://www.example.com/regexp.html'
+ assert_response :not_found
+ end
+end
+
class TestRouteDefaults < ActionDispatch::IntegrationTest
stub_controllers do |routes|
Routes = routes

0 comments on commit 923ec86

Please sign in to comment.
Something went wrong with that request. Please try again.