1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
# frozen_string_literal: true
require "action_dispatch/routing/polymorphic_routes"
module ActionView
module RoutingUrlFor
# Returns the URL for the set of +options+ provided. This takes the
# same options as +url_for+ in Action Controller (see the
# documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
# <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action"
# instead of the fully qualified URL like "http://example.com/controller/action".
#
# ==== Options
# * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path.
# * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified).
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this
# is currently not recommended since it breaks caching.
# * <tt>:host</tt> - Overrides the default (current) host if provided.
# * <tt>:protocol</tt> - Overrides the default (current) protocol if provided.
# * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present).
# * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present).
#
# ==== Relying on named routes
#
# Passing a record (like an Active Record) instead of a hash as the options parameter will
# trigger the named route for that record. The lookup will happen on the name of the class. So passing a
# Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as
# +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route).
#
# ==== Implicit Controller Namespacing
#
# Controllers passed in using the +:controller+ option will retain their namespace unless it is an absolute one.
#
# ==== Examples
# <%= url_for(action: 'index') %>
# # => /blogs/
#
# <%= url_for(action: 'find', controller: 'books') %>
# # => /books/find
#
# <%= url_for(action: 'login', controller: 'members', only_path: false, protocol: 'https') %>
# # => https://www.example.com/members/login/
#
# <%= url_for(action: 'play', anchor: 'player') %>
# # => /messages/play/#player
#
# <%= url_for(action: 'jump', anchor: 'tax&ship') %>
# # => /testing/jump/#tax&ship
#
# <%= url_for(Workshop.new) %>
# # relies on Workshop answering a persisted? call (and in this case returning false)
# # => /workshops
#
# <%= url_for(@workshop) %>
# # calls @workshop.to_param which by default returns the id
# # => /workshops/5
#
# # to_param can be re-defined in a model to provide different URL names:
# # => /workshops/1-workshop-name
#
# <%= url_for("http://www.example.com") %>
# # => http://www.example.com
#
# <%= url_for(:back) %>
# # if request.env["HTTP_REFERER"] is set to "http://www.example.com"
# # => http://www.example.com
#
# <%= url_for(:back) %>
# # if request.env["HTTP_REFERER"] is not set or is blank
# # => javascript:history.back()
#
# <%= url_for(action: 'index', controller: 'users') %>
# # Assuming an "admin" namespace
# # => /admin/users
#
# <%= url_for(action: 'index', controller: '/users') %>
# # Specify absolute path with beginning slash
# # => /users
def url_for(options = nil)
case options
when String
options
when nil
super(only_path: _generate_paths_by_default)
when Hash
options = options.symbolize_keys
ensure_only_path_option(options)
super(options)
when ActionController::Parameters
ensure_only_path_option(options)
super(options)
when :back
_back_url
when Array
components = options.dup
options = components.extract_options!
ensure_only_path_option(options)
if options[:only_path]
polymorphic_path(components, options)
else
polymorphic_url(components, options)
end
else
method = _generate_paths_by_default ? :path : :url
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method)
case options
when Symbol
builder.handle_string_call(self, options)
when Class
builder.handle_class_call(self, options)
else
builder.handle_model_call(self, options)
end
end
end
def url_options #:nodoc:
return super unless controller.respond_to?(:url_options)
controller.url_options
end
private
def _routes_context
controller
end
def optimize_routes_generation?
controller.respond_to?(:optimize_routes_generation?, true) ?
controller.optimize_routes_generation? : super
end
def _generate_paths_by_default
true
end
def ensure_only_path_option(options)
unless options.key?(:only_path)
options[:only_path] = _generate_paths_by_default unless options[:host]
end
end
end
end
|