mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
use a strategy object for generating urls in named helpers
since we know that the route should be a path or fully qualified, we can pass a strategy object that handles generation. This allows us to eliminate an "if only_path" branch when generating urls.
This commit is contained in:
parent
a9765c54ea
commit
2888f8653e
2 changed files with 37 additions and 21 deletions
|
@ -29,20 +29,25 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
def url_for(options)
|
||||
host = options[:host]
|
||||
unless host || options[:only_path]
|
||||
raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
|
||||
end
|
||||
|
||||
if options[:only_path]
|
||||
path_for options
|
||||
else
|
||||
protocol = options[:protocol]
|
||||
port = options[:port]
|
||||
build_host_url(host, port, protocol, options, path_for(options))
|
||||
full_url_for options
|
||||
end
|
||||
end
|
||||
|
||||
def full_url_for(options)
|
||||
host = options[:host]
|
||||
protocol = options[:protocol]
|
||||
port = options[:port]
|
||||
|
||||
unless host
|
||||
raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
|
||||
end
|
||||
|
||||
build_host_url(host, port, protocol, options, path_for(options))
|
||||
end
|
||||
|
||||
def path_for(options)
|
||||
result = options[:script_name].to_s.chomp("/")
|
||||
result << options[:path].to_s
|
||||
|
|
|
@ -134,11 +134,11 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
class UrlHelper # :nodoc:
|
||||
def self.create(route, options)
|
||||
def self.create(route, options, url_strategy)
|
||||
if optimize_helper?(route)
|
||||
OptimizedUrlHelper.new(route, options)
|
||||
OptimizedUrlHelper.new(route, options, url_strategy)
|
||||
else
|
||||
new route, options
|
||||
new route, options, url_strategy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -146,10 +146,12 @@ module ActionDispatch
|
|||
!route.glob? && route.path.requirements.empty?
|
||||
end
|
||||
|
||||
attr_reader :url_strategy
|
||||
|
||||
class OptimizedUrlHelper < UrlHelper # :nodoc:
|
||||
attr_reader :arg_size
|
||||
|
||||
def initialize(route, options)
|
||||
def initialize(route, options, url_strategy)
|
||||
super
|
||||
@required_parts = @route.required_parts
|
||||
@arg_size = @required_parts.size
|
||||
|
@ -159,7 +161,7 @@ module ActionDispatch
|
|||
if args.size == arg_size && !inner_options && optimize_routes_generation?(t)
|
||||
options = t.url_options.merge @options
|
||||
options[:path] = optimized_helper(args)
|
||||
ActionDispatch::Http::URL.url_for(options)
|
||||
url_strategy.call options
|
||||
else
|
||||
super
|
||||
end
|
||||
|
@ -201,10 +203,11 @@ module ActionDispatch
|
|||
end
|
||||
end
|
||||
|
||||
def initialize(route, options)
|
||||
def initialize(route, options, url_strategy)
|
||||
@options = options
|
||||
@segment_keys = route.segment_keys.uniq
|
||||
@route = route
|
||||
@url_strategy = url_strategy
|
||||
end
|
||||
|
||||
def call(t, args, inner_options)
|
||||
|
@ -216,7 +219,7 @@ module ActionDispatch
|
|||
options,
|
||||
@segment_keys)
|
||||
|
||||
t._routes.url_for(hash)
|
||||
t._routes.url_for(hash, url_strategy)
|
||||
end
|
||||
|
||||
def handle_positional_args(controller_options, inner_options, args, result, path_params)
|
||||
|
@ -249,8 +252,8 @@ module ActionDispatch
|
|||
#
|
||||
# foo_url(bar, baz, bang, sort_by: 'baz')
|
||||
#
|
||||
def define_url_helper(route, name, opts)
|
||||
helper = UrlHelper.create(route, opts)
|
||||
def define_url_helper(route, name, opts, url_strategy)
|
||||
helper = UrlHelper.create(route, opts, url_strategy)
|
||||
|
||||
@module.remove_possible_method name
|
||||
@module.module_eval do
|
||||
|
@ -266,12 +269,20 @@ module ActionDispatch
|
|||
|
||||
def define_named_route_methods(name, route)
|
||||
define_url_helper route, :"#{name}_path",
|
||||
route.defaults.merge(:use_route => name, :only_path => true)
|
||||
route.defaults.merge(:use_route => name), PATH
|
||||
|
||||
define_url_helper route, :"#{name}_url",
|
||||
route.defaults.merge(:use_route => name, :only_path => false)
|
||||
route.defaults.merge(:use_route => name), FULL
|
||||
end
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
# strategy for building urls to send to the client
|
||||
PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
|
||||
FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
|
||||
UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) }
|
||||
# :startdoc:
|
||||
|
||||
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
|
||||
attr_accessor :disable_clear_and_finalize, :resources_path_names
|
||||
attr_accessor :default_url_options, :request_class
|
||||
|
@ -643,7 +654,7 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
# The +options+ argument must be a hash whose keys are *symbols*.
|
||||
def url_for(options)
|
||||
def url_for(options, url_strategy = UNKNOWN)
|
||||
options = default_url_options.merge options
|
||||
|
||||
user = password = nil
|
||||
|
@ -677,7 +688,7 @@ module ActionDispatch
|
|||
options[:user] = user
|
||||
options[:password] = password
|
||||
|
||||
ActionDispatch::Http::URL.url_for(options)
|
||||
url_strategy.call options
|
||||
end
|
||||
|
||||
def call(env)
|
||||
|
|
Loading…
Reference in a new issue