модуль ActionDispatch::Routing::UrlFor
Action Dispatch Routing UrlFor
В config/routes.rb задаются соответствия URL и контроллеров, но возможно и обратное: URL можно сгенерировать на основе одного из определений маршрутов. Функциональность генерации URL централизована в этом модуле.
Общие сведения о маршрутизации и config/routes.rb см. в разделе ActionDispatch::Routing.
Совет: Если вам нужно генерировать 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 также позволяет обращаться к методам, автоматически созданным для именованных маршрутов. Например, предположим, что в вашем config/routes.rb есть ресурс ‘users’:
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 111 def initialize(...) @_routes = nil super end
Открытые методы экземпляра
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 222
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 178 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— указывает хост, на который должна вести ссылка. Если:only_pathимеет значение false, этот параметр необходимо передать явно или задать черезdefault_url_options. -
:subdomain— указывает поддомен ссылки, используяtld_lengthдля отделения поддомена от хоста. Если значение false, все поддомены удаляются из части ссылки с хостом. -
: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'
Обратите внимание, что в первом вызове url_for параметр :id не был передан, и помощник использовал его из пути маршрута. Любой параметр пути, неявно используемый url_for, всегда можно переопределить, как показано в последних вызовах url_for.
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 118 def url_options default_url_options end
Хук переопределяется в контроллере для добавления сведений о запросе с помощью default_url_options. Логику приложения не следует помещать в url_options.
Защищенные методы экземпляра
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 227 def optimize_routes_generation? _routes.optimize_routes_generation? && default_url_options.empty? end
Закрытые методы экземпляра
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 239 def _routes_context # :doc: self end
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 232 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.