未验证 提交 643cac08 编写于 作者: J Jeremy Daer

Merge pull request #23103 from rails/refactor-handling-of-action-default

Refactor handling of :action default in routing
* Routing: Refactor `:action` default handling to ensure that path
parameters are not mutated during route generation.
*Andrew White*
* Add extension synonyms `yml` and `yaml` for MIME type `application/x-yaml`.
*bogdanvlviv*
*bogdanvlviv*
* Adds support for including ActionController::Cookies in API controllers.
Previously, including the module would raise when trying to define
......
......@@ -32,8 +32,13 @@ def generate(name, options, path_parameters, parameterize = nil)
defaults = route.defaults
required_parts = route.required_parts
parameterized_parts.keep_if do |key, value|
(defaults[key].nil? && value.present?) || value.to_s != defaults[key].to_s || required_parts.include?(key)
route.parts.reverse_each do |key|
break if defaults[key].nil? && parameterized_parts[key].present?
break if parameterized_parts[key].to_s != defaults[key].to_s
break if required_parts.include?(key)
parameterized_parts.delete(key)
end
return [route.format(parameterized_parts), params]
......
......@@ -33,11 +33,11 @@ def reqs
end
def controller
requirements[:controller] || ':controller'
parts.include?(:controller) ? ':controller' : requirements[:controller]
end
def action
requirements[:action] || ':action'
parts.include?(:action) ? ':action' : requirements[:action]
end
def internal?
......
......@@ -137,6 +137,10 @@ def initialize(set, ast, defaults, controller, default_action, modyoule, to, for
@conditions = Hash[conditions]
@defaults = formats[:defaults].merge(@defaults).merge(normalize_defaults(options))
if path_params.include?(:action) && !@requirements.key?(:action)
@defaults[:action] ||= 'index'
end
@required_defaults = (split_options[:required_defaults] || []).map(&:first)
end
......
......@@ -548,12 +548,10 @@ def initialize(named_route, options, recall, set)
@recall = recall
@set = set
normalize_recall!
normalize_options!
normalize_controller_action_id!
use_relative_controller!
normalize_controller!
normalize_action!
end
def controller
......@@ -572,11 +570,6 @@ def use_recall_for(key)
end
end
# Set 'index' as default action for recall
def normalize_recall!
@recall[:action] ||= 'index'
end
def normalize_options!
# If an explicit :controller was given, always make :action explicit
# too, so that action expiry works as expected for things like
......@@ -630,13 +623,6 @@ def normalize_controller!
end
end
# Move 'index' action from options to recall
def normalize_action!
if @options[:action] == 'index'.freeze
@recall[:action] = @options.delete(:action)
end
end
# Generates a path from routes, returns [path, params].
# If no route is generated the formatter will raise ActionController::UrlGenerationError
def generate
......
......@@ -2064,11 +2064,11 @@ def test_generate_extras
def test_extras
params = {:controller => 'people'}
assert_equal [], @routes.extra_keys(params)
assert_equal({:controller => 'people'}, params)
assert_equal({:controller => 'people', :action => 'index'}, params)
params = {:controller => 'people', :foo => 'bar'}
assert_equal [:foo], @routes.extra_keys(params)
assert_equal({:controller => 'people', :foo => 'bar'}, params)
assert_equal({:controller => 'people', :action => 'index', :foo => 'bar'}, params)
params = {:controller => 'people', :action => 'create', :person => { :name => 'Josh'}}
assert_equal [:person], @routes.extra_keys(params)
......
......@@ -347,7 +347,7 @@ def test_regression_route_with_controller_regexp
end
assert_equal ["Prefix Verb URI Pattern Controller#Action",
" GET /:controller(/:action) (?-mix:api\\/[^\\/]+)#:action"], output
" GET /:controller(/:action) :controller#:action"], output
end
def test_inspect_routes_shows_resources_route_when_assets_disabled
......
......@@ -3991,16 +3991,6 @@ def app; APP end
end
class TestMultipleNestedController < ActionDispatch::IntegrationTest
module ::Foo
module Bar
class BazController < ActionController::Base
def index
render :inline => "<%= url_for :controller => '/pooh', :action => 'index' %>"
end
end
end
end
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
namespace :foo do
......@@ -4012,7 +4002,18 @@ def index
end
end
include Routes.url_helpers
module ::Foo
module Bar
class BazController < ActionController::Base
include Routes.url_helpers
def index
render :inline => "<%= url_for :controller => '/pooh', :action => 'index' %>"
end
end
end
end
APP = build_app Routes
def app; APP end
......@@ -4755,3 +4756,42 @@ def assert_params(params)
assert_equal(params, request.path_parameters)
end
end
class TestPathParameters < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
scope module: 'test_path_parameters' do
scope ':locale', locale: /en|ar/ do
root to: 'home#index'
get '/about', to: 'pages#about'
end
end
get ':controller(/:action/(:id))'
end
end
class HomeController < ActionController::Base
include Routes.url_helpers
def index
render inline: "<%= root_path %>"
end
end
class PagesController < ActionController::Base
include Routes.url_helpers
def about
render inline: "<%= root_path(locale: :ar) %> | <%= url_for(locale: :ar) %>"
end
end
APP = build_app Routes
def app; APP end
def test_path_parameters_are_not_mutated
get '/en/about'
assert_equal "/ar | /ar/about", @response.body
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册