mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
parent
0d48b12fc5
commit
9b4514c3b8
4 changed files with 69 additions and 3 deletions
|
@ -1,5 +1,10 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* Copy literal route constraints to defaults so that url generation know about them.
|
||||
The copied constraints are `:protocol`, `:subdomain`, `:domain`, `:host` and `:port`.
|
||||
|
||||
*Andrew White*
|
||||
|
||||
* `respond_to` and `respond_with` now raise ActionController::UnknownFormat instead
|
||||
of directly returning head 406. The exception is rescued and converted to 406
|
||||
in the exception handling middleware. *Steven Soroka*
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'active_support/core_ext/hash/except'
|
||||
require 'active_support/core_ext/hash/reverse_merge'
|
||||
require 'active_support/core_ext/hash/slice'
|
||||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/core_ext/enumerable'
|
||||
require 'active_support/inflector'
|
||||
|
@ -100,6 +101,10 @@ module ActionDispatch
|
|||
raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
if @options[:constraints].is_a?(Hash)
|
||||
(@options[:defaults] ||= {}).reverse_merge!(defaults_from_constraints(@options[:constraints]))
|
||||
end
|
||||
end
|
||||
|
||||
# match "account/overview"
|
||||
|
@ -245,6 +250,11 @@ module ActionDispatch
|
|||
def default_action
|
||||
@options[:action] || @scope[:action]
|
||||
end
|
||||
|
||||
def defaults_from_constraints(constraints)
|
||||
url_keys = [:protocol, :subdomain, :domain, :host, :port]
|
||||
constraints.slice(*url_keys).select{ |k, v| v.is_a?(String) || v.is_a?(Fixnum) }
|
||||
end
|
||||
end
|
||||
|
||||
# Invokes Rack::Mount::Utils.normalize path and ensure that
|
||||
|
@ -641,6 +651,10 @@ module ActionDispatch
|
|||
block, options[:constraints] = options[:constraints], {}
|
||||
end
|
||||
|
||||
if options[:constraints].is_a?(Hash)
|
||||
(options[:defaults] ||= {}).reverse_merge!(defaults_from_constraints(options[:constraints]))
|
||||
end
|
||||
|
||||
scope_options.each do |option|
|
||||
if value = options.delete(option)
|
||||
recover[option] = @scope[option]
|
||||
|
@ -849,6 +863,11 @@ module ActionDispatch
|
|||
def override_keys(child) #:nodoc:
|
||||
child.key?(:only) || child.key?(:except) ? [:only, :except] : []
|
||||
end
|
||||
|
||||
def defaults_from_constraints(constraints)
|
||||
url_keys = [:protocol, :subdomain, :domain, :host, :port]
|
||||
constraints.slice(*url_keys).select{ |k, v| v.is_a?(String) || v.is_a?(Fixnum) }
|
||||
end
|
||||
end
|
||||
|
||||
# Resource routing allows you to quickly declare all of the common routes
|
||||
|
|
|
@ -47,7 +47,7 @@ class RoutingAssertionsTest < ActionController::TestCase
|
|||
def test_assert_recognizes_with_extras
|
||||
assert_recognizes({ :controller => 'articles', :action => 'index', :page => '1' }, '/articles', { :page => '1' })
|
||||
end
|
||||
|
||||
|
||||
def test_assert_recognizes_with_method
|
||||
assert_recognizes({ :controller => 'articles', :action => 'create' }, { :path => '/articles', :method => :post })
|
||||
assert_recognizes({ :controller => 'articles', :action => 'update', :id => '1' }, { :path => '/articles/1', :method => :put })
|
||||
|
@ -57,7 +57,7 @@ class RoutingAssertionsTest < ActionController::TestCase
|
|||
assert_raise(ActionController::RoutingError) do
|
||||
assert_recognizes({ :controller => 'secure_articles', :action => 'index' }, 'http://test.host/secure/articles')
|
||||
end
|
||||
assert_recognizes({ :controller => 'secure_articles', :action => 'index' }, 'https://test.host/secure/articles')
|
||||
assert_recognizes({ :controller => 'secure_articles', :action => 'index', :protocol => 'https://' }, 'https://test.host/secure/articles')
|
||||
end
|
||||
|
||||
def test_assert_recognizes_with_block_constraint
|
||||
|
@ -90,7 +90,7 @@ class RoutingAssertionsTest < ActionController::TestCase
|
|||
assert_raise(ActionController::RoutingError) do
|
||||
assert_routing('http://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index' })
|
||||
end
|
||||
assert_routing('https://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index' })
|
||||
assert_routing('https://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index', :protocol => 'https://' })
|
||||
end
|
||||
|
||||
def test_assert_routing_with_block_constraint
|
||||
|
|
|
@ -2606,3 +2606,45 @@ class TestNamedRouteUrlHelpers < ActionDispatch::IntegrationTest
|
|||
assert_raises(ActionController::RoutingError) { product_path(nil) }
|
||||
end
|
||||
end
|
||||
|
||||
class TestUrlConstraints < ActionDispatch::IntegrationTest
|
||||
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
||||
app.draw do
|
||||
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
||||
|
||||
constraints :subdomain => 'admin' do
|
||||
get '/' => ok, :as => :admin_root
|
||||
end
|
||||
|
||||
scope :constraints => { :protocol => 'https://' } do
|
||||
get '/' => ok, :as => :secure_root
|
||||
end
|
||||
|
||||
get '/' => ok, :as => :alternate_root, :constraints => { :port => 8080 }
|
||||
end
|
||||
end
|
||||
|
||||
include Routes.url_helpers
|
||||
def app; Routes end
|
||||
|
||||
test "constraints are copied to defaults when using constraints method" do
|
||||
assert_equal 'http://admin.example.com/', admin_root_url
|
||||
|
||||
get 'http://admin.example.com/'
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "constraints are copied to defaults when using scope constraints hash" do
|
||||
assert_equal 'https://www.example.com/', secure_root_url
|
||||
|
||||
get 'https://www.example.com/'
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "constraints are copied to defaults when using route constraints hash" do
|
||||
assert_equal 'http://www.example.com:8080/', alternate_root_url
|
||||
|
||||
get 'http://www.example.com:8080/'
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue