модуль ActionDispatch::Routing::UrlFor
Action Dispatch Routing UrlFor
В config/routes.rb вы определяете сопоставления URL-адресов с контроллерами, но обратное тоже возможно: URL-адрес можно сгенерировать по одному из ваших маршрутных определений. Функциональность генерации URL-адресов централизована в этом модуле.
См. ActionDispatch::Routing для общей информации о маршрутизации и config/routes.rb.
Подсказка: Если вам нужно генерировать URL-адреса из ваших моделей или из других мест, то ActionDispatch::Routing::UrlFor — то, что вам нужно. Читайте далее для введения. В общем случае, этот модуль не следует включать самостоятельно, так как он обычно включается url_helpers (как в Rails.application.routes.url_helpers).
Генерация URL-адресов из параметров
Как вы знаете, некоторые функции, такие как ActionController::Base#url_for и ActionView::Helpers::UrlHelper#link_to, могут генерировать URL-адреса, заданные набором параметров. Например, вы, вероятно, имели возможность написать код подобный этому в одном из ваших представлений:
<%= link_to('Click here', controller: 'users',
action: 'new', message: 'Welcome!') %>
# => <a href="/users/new?message=Welcome%21">Click here</a> link_to, и все остальные функции, которые требуют функциональности генерации URL-адресов, фактически используют ActionDispatch::Routing::UrlFor в скрытом режиме. И, в частности, они используют метод ActionDispatch::Routing::UrlFor#url_for. Можно сгенерировать тот же путь, что и в приведенном выше примере, используя следующий код:
include ActionDispatch::Routing::UrlFor
url_for(controller: 'users',
action: 'new',
message: 'Welcome!',
only_path: true)
# => "/users/new?message=Welcome%21"
Обратите внимание на only_path: true часть. Это потому, что UrlFor не имеет информации о доменном имени сайта, на котором обслуживается ваше приложение Rails. Поэтому, если вы хотите включить доменное имя, вам также необходимо передать параметр :host:
include UrlFor
url_for(controller: 'users',
action: 'new',
message: 'Welcome!',
host: 'www.example.com')
# => "http://www.example.com/users/new?message=Welcome%21"
По умолчанию все контроллеры и представления имеют доступ к специальной версии url_for, которая уже знает текущее доменное имя. Поэтому, если вы используете url_for в своих контроллерах или представлениях, вам не нужно явно передавать параметр :host.
Для удобства, почтовые сообщения также включают ActionDispatch::Routing::UrlFor. Поэтому в почтовых сообщениях можно использовать url_for. Однако почтовые сообщения не могут получить доступ к входящим веб-запросам для получения информации о доменном имени, поэтому вы должны предоставить опцию :host или установить значение по умолчанию для хоста с помощью default_url_options. Для получения дополнительной информации о url_for в почтовых сообщениях см. документацию по ActionMailer::Base.
Генерация URL-адресов для именованных маршрутов
UrlFor также позволяет получить доступ к методам, которые были автоматически сгенерированы из именованных маршрутов. Например, предположим, что у вас есть ресурс «users» в вашей config/routes.rb:
resources :users
Это генерирует, среди прочего, метод users_path. По умолчанию этот метод доступен из ваших контроллеров, представлений и почтовых сообщений. Если вам нужно получить доступ к этому автоматически сгенерированному методу из других мест (например, из модели), то вы можете сделать это, включив Rails.application.routes.url_helpers в ваш класс:
class User < ActiveRecord::Base
include Rails.application.routes.url_helpers
def base_uri
user_path(self)
end
end
User.find(1).base_uri # => "/users/1"
Методы публичного класса
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 108 def initialize(...) @_routes = nil super end
Методы публичного экземпляра
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 217
def route_for(name, *args)
public_send(:"#{name}_url", *args)
end Позволяет вызывать прямой или обычный маршрут по имени.
resources :buckets direct :recordable do |recording| route_for(:bucket, recording.bucket) end direct :threadable do |threadable| route_for(:recordable, threadable.parent) end
Это сохраняет контекст исходного вызывающего, о том, возвращать ли путь или полный URL, например:
threadable_path(threadable) # => "/buckets/1" threadable_url(threadable) # => "http://example.com/buckets/1"
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 173 def url_for(options = nil) full_url_for(options) end
Генерирует URL на основе предоставленных параметров, default_url_options, и маршрутов, определённых в config/routes.rb. Поддерживаются следующие параметры:
-
:only_path- Если true, возвращается относительный URL. По умолчаниюfalse. -
:protocol- Протокол подключения. По умолчанию"http". -
:host- Указывает хост, к которому должен быть направлен link. Если:only_pathложно, этот параметр должен быть предоставлен явно или черезdefault_url_options. -
:subdomain- Указывает поддомен ссылки, используяtld_lengthдля разделения поддомена и хоста. Если ложно, удаляет все поддомены из части хоста ссылки. -
:domain- Указывает домен ссылки, используяtld_lengthдля разделения домена и хоста. -
:tld_length- Количество меток, из которых состоит TLD, используется только если:subdomainили:domainпредоставлены. По умолчаниюActionDispatch::Http::URL.tld_length, что по умолчанию равно 1. -
:port- Необязательно укажите порт для подключения. -
:anchor- Имя якоря, которое будет добавлено к пути. -
:params- Параметры запроса, которые будут добавлены к пути. -
:path_params- Параметры запроса, которые будут использоваться только для динамических сегментов пути по имени. Если не используются, они будут отброшены. -
:trailing_slash- Если true, добавляет слеш в конце, как в"/archive/2009/". -
:script_name- Указывает путь приложения относительно корня домена. При предоставлении добавляет путь приложения в начало.
Любой другой ключ (:controller, :action, и т. д.) переданный в url_for, передается модулю Routes.
url_for controller: 'tasks', action: 'testing', host: 'somehost.org', port: '8080' # => 'http://somehost.org:8080/tasks/testing' url_for controller: 'tasks', action: 'testing', host: 'somehost.org', anchor: 'ok', only_path: true # => '/tasks/testing#ok' url_for controller: 'tasks', action: 'testing', trailing_slash: true # => 'http://somehost.org/tasks/testing/' url_for controller: 'tasks', action: 'testing', host: 'somehost.org', number: '33' # => 'http://somehost.org/tasks/testing?number=33' url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp" # => 'http://somehost.org/myapp/tasks/testing' url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true # => '/myapp/tasks/testing'
Пропущенные ключи маршрутов могут быть заполнены параметрами текущего запроса (например, :controller, :action, :id, и любые другие параметры, размещенные в пути). С учётом того, что текущее действие достигнуто через GET /users/1:
url_for(only_path: true) # => '/users/1' url_for(only_path: true, action: 'edit') # => '/users/1/edit' url_for(only_path: true, action: 'edit', id: 2) # => '/users/2/edit'
Обратите внимание, что параметр :id не был предоставлен первому вызову url_for, и помощник использовал параметр из пути маршрута. Любой путь параметр, неявно используемый url_for, может быть переопределен, как показано в последних вызовах url_for.
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 116 def url_options default_url_options end
Переопределенный в контроллере крючок для добавления информации о запросе с default_url_options. Логика приложения не должна включаться в url_options.
Защищенные методы экземпляра
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 222 def optimize_routes_generation? _routes.optimize_routes_generation? && default_url_options.empty? end
Приватные методы экземпляра
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 234 def _routes_context # :doc: self end
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 227 def _with_routes(routes) # :doc: old_routes, @_routes = @_routes, routes yield ensure @_routes = old_routes end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.