aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/routing
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb27
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb20
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb8
3 files changed, 48 insertions, 7 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index a2570cb877..f3aa09f4a7 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -261,7 +261,11 @@ module ActionDispatch
raise "A rack application must be specified" unless path
+ options[:as] ||= app_name(app)
+
match(path, options.merge(:to => app, :anchor => false, :format => false))
+
+ define_generate_prefix(app, options[:as])
self
end
@@ -269,6 +273,29 @@ module ActionDispatch
@set.default_url_options = options
end
alias_method :default_url_options, :default_url_options=
+
+ private
+ def app_name(app)
+ return unless app.respond_to?(:routes)
+ class_name = app.class.is_a?(Class) ? app.name : app.class.name
+ ActiveSupport::Inflector.underscore(class_name).gsub("/", "_")
+ end
+
+ def define_generate_prefix(app, name)
+ return unless app.respond_to?(:routes)
+
+ _route = @set.named_routes.routes[name.to_sym]
+ _router = @set
+ app.routes.class_eval do
+ define_method :_generate_prefix do |options|
+ keys = _route.segment_keys + ActionDispatch::Routing::RouteSet::RESERVED_OPTIONS
+ prefix_options = options.reject { |k, v| !(keys).include?(k) }
+ # we must actually delete prefix segment keys to avoid passing them to next url_for
+ _route.segment_keys.each { |k| options.delete(k) }
+ _router.url_helpers.send("#{name}_path", prefix_options)
+ end
+ end
+ end
end
module HttpHelpers
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index b531cc1a8e..cb0373951f 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -303,10 +303,9 @@ module ActionDispatch
end
class Generator #:nodoc:
- attr_reader :options, :recall, :set, :script_name, :named_route
+ attr_reader :options, :recall, :set, :named_route
def initialize(options, recall, set, extras = false)
- @script_name = options.delete(:script_name)
@named_route = options.delete(:use_route)
@options = options.dup
@recall = recall.dup
@@ -401,7 +400,7 @@ module ActionDispatch
return [path, params.keys] if @extras
path << "?#{params.to_query}" if params.any?
- "#{script_name}#{path}"
+ path
rescue Rack::Mount::RoutingError
raise_routing_error
end
@@ -453,7 +452,11 @@ module ActionDispatch
Generator.new(options, recall, self, extras).generate
end
- RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash]
+ RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :script_name, :skip_prefix, :routes]
+
+ def _generate_prefix(options = {})
+ nil
+ end
def url_for(options)
finalize!
@@ -464,7 +467,6 @@ module ActionDispatch
rewritten_url = ""
path_segments = options.delete(:_path_segments)
-
unless options[:only_path]
rewritten_url << (options[:protocol] || "http")
rewritten_url << "://" unless rewritten_url.match("://")
@@ -476,9 +478,15 @@ module ActionDispatch
rewritten_url << ":#{options.delete(:port)}" if options.key?(:port)
end
+ path = [options.delete(:script_name)]
+ if !options.delete(:skip_prefix)
+ path << _generate_prefix(options)
+ end
+
path_options = options.except(*RESERVED_OPTIONS)
path_options = yield(path_options) if block_given?
- path = generate(path_options, path_segments || {})
+ path << generate(path_options, path_segments || {})
+ path = path.compact.join ''
# ROUTES TODO: This can be called directly, so script_name should probably be set in the routes
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index 28ec830fe8..f73067688c 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -128,7 +128,13 @@ module ActionDispatch
when String
options
when nil, Hash
- _routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys)
+ routes = (options ? options.delete(:routes) : nil) || _routes
+
+ if respond_to?(:env) && env && routes.equal?(env["action_dispatch.routes"])
+ options[:skip_prefix] = true
+ end
+
+ routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys)
else
polymorphic_url(options)
end