Skip to content

Commit

Permalink
Routes may be restricted to lists of HTTP methods instead of a single…
Browse files Browse the repository at this point in the history
… method or :any.

[#407 state:resolved]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information
brennandunn authored and jeremy committed Aug 28, 2008
1 parent 7bdd5b7 commit 9cc8c0a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
4 changes: 4 additions & 0 deletions actionpack/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
*Edge*

* Routes may be restricted to lists of HTTP methods instead of a single method or :any. #407 [Brennan Dunn, Gaius Centus Novus]
map.resource :posts, :collection => { :search => [:get, :post] }
map.session 'session', :requirements => { :method => [:get, :post, :delete] }

* Deprecated implicit local assignments when rendering partials [Josh Peek]

* Introduce current_cycle helper method to return the current value without bumping the cycle. #417 [Ken Collins]
Expand Down
12 changes: 7 additions & 5 deletions actionpack/lib/action_controller/routing/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,14 @@ def build(path, options)
private
def validate_route_conditions(conditions)
if method = conditions[:method]
if method == :head
raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
end
[method].flatten.each do |m|
if m == :head
raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
end

unless HTTP_METHODS.include?(method.to_sym)
raise ArgumentError, "Invalid HTTP method specified in route conditions: #{conditions.inspect}"
unless HTTP_METHODS.include?(m.to_sym)
raise ArgumentError, "Invalid HTTP method specified in route conditions: #{conditions.inspect}"
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller/routing/route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def write_recognition!
# recognition, not generation.
def recognition_conditions
result = ["(match = #{Regexp.new(recognition_pattern).inspect}.match(path))"]
result << "conditions[:method] === env[:method]" if conditions[:method]
result << "[conditions[:method]].flatten.include?(env[:method])" if conditions[:method]
result
end

Expand Down
25 changes: 25 additions & 0 deletions actionpack/test/controller/routing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,31 @@ def setup_request_method_routes_for(method)
end
end

def test_recognize_array_of_methods
begin
Object.const_set(:BooksController, Class.new(ActionController::Base))
rs.draw do |r|
r.connect '/match', :controller => 'books', :action => 'get_or_post', :conditions => { :method => [:get, :post] }
r.connect '/match', :controller => 'books', :action => 'not_get_or_post'
end

@request = ActionController::TestRequest.new
@request.env["REQUEST_METHOD"] = 'POST'
@request.request_uri = "/match"
assert_nothing_raised { rs.recognize(@request) }
assert_equal 'get_or_post', @request.path_parameters[:action]

# have to recreate or else the RouteSet uses a cached version:
@request = ActionController::TestRequest.new
@request.env["REQUEST_METHOD"] = 'PUT'
@request.request_uri = "/match"
assert_nothing_raised { rs.recognize(@request) }
assert_equal 'not_get_or_post', @request.path_parameters[:action]
ensure
Object.send(:remove_const, :BooksController) rescue nil
end
end

def test_subpath_recognized
Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))

Expand Down

0 comments on commit 9cc8c0a

Please sign in to comment.