Spec-Zone.ru › Ruby on Rails 8.1

модуль ActionDispatch::Routing::UrlFor

Включенные модули:
ActionDispatch::Routing::PolymorphicRoutes

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"

Открытые методы класса

new (...) Показать исходный код
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 111
def initialize(...)
  @_routes = nil
  super
end
Вызывает метод суперкласса

Открытые методы экземпляра

route_for (name, *args) Показать исходный код
# 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"
url_for (options = nil) Показать исходный код
# 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.

url_options () Показать исходный код
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 118
def url_options
  default_url_options
end

Хук переопределяется в контроллере для добавления сведений о запросе с помощью default_url_options. Логику приложения не следует помещать в url_options.

Защищенные методы экземпляра

optimize_routes_generation? () Показать исходный код
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 227
def optimize_routes_generation?
  _routes.optimize_routes_generation? && default_url_options.empty?
end

Закрытые методы экземпляра

_routes_context () Показать исходный код
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 239
def _routes_context # :doc:
  self
end
_with_routes (routes) { || ... } Показать исходный код
# 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API