Spec-Zone.ru › Ruby on Rails 8.0

модуль ActionView::Helpers::UrlHelper

Включенные модули:
ActionView::Helpers::TagHelper, ActionView::Helpers::ContentExfiltrationPreventionHelper

Справочник по URL-помощникам Action View

Предоставляет набор методов для создания ссылок и получения URL-адресов, зависящих от подсистемы маршрутизации (см. ActionDispatch::Routing). Это позволяет использовать один и тот же формат для ссылок в представлениях и контроллерах.

Константы

BUTTON_TAG_METHOD_VERBS

Этот помощник может быть включён в любой класс, включающий помощники URL маршрутов (routes.url_helpers). Некоторые методы, представленные здесь, будут работать только в контексте запроса (link_to_unless_current, например), который должен быть предоставлен как метод, называемый request в контексте.

STRINGIFIED_COMMON_METHODS

Методы общедоступного экземпляра

button_to(name = nil, options = nil, html_options = nil, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 296
def button_to(name = nil, options = nil, html_options = nil, &block)
  html_options, options = options, name if block_given?
  html_options ||= {}
  html_options = html_options.stringify_keys

  url =
    case options
    when FalseClass then nil
    else url_for(options)
    end

  remote = html_options.delete("remote")
  params = html_options.delete("params")

  authenticity_token = html_options.delete("authenticity_token")

  method     = (html_options.delete("method").presence || method_for_options(options)).to_s
  method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".html_safe

  form_method  = method == "get" ? "get" : "post"
  form_options = html_options.delete("form") || {}
  form_options[:class] ||= html_options.delete("form_class") || "button_to"
  form_options[:method] = form_method
  form_options[:action] = url
  form_options[:'data-remote'] = true if remote

  request_token_tag = if form_method == "post"
    request_method = method.empty? ? "post" : method
    token_tag(authenticity_token, form_options: { action: url, method: request_method })
  else
    ""
  end

  html_options = convert_options_to_data_attributes(options, html_options)
  html_options["type"] = "submit"

  button = if block_given?
    content_tag("button", html_options, &block)
  elsif button_to_generates_button_tag
    content_tag("button", name || url, html_options, &block)
  else
    html_options["value"] = name || url
    tag("input", html_options)
  end

  inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
  if params
    to_form_params(params).each do |param|
      inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value],
                                 autocomplete: "off")
    end
  end
  html = content_tag("form", inner_tags, form_options)
  prevent_content_exfiltration(html)
end

Генерирует форму, содержащую одну кнопку, которая отправляет запрос на URL, созданный набором options. Это самый безопасный метод для того, чтобы ссылки, вызывающие изменения в ваших данных, не запускались ботами или ускорителями поиска.

Вы можете управлять поведением формы и кнопки с помощью html_options. Большинство значений в html_options передаются в элемент кнопки. Например, передача параметра :class в html_options установит атрибут класса элемента кнопки.

Атрибут класса элемента формы можно задать, передав параметр :form_class в html_options. По умолчанию используется "button_to" для форматирования формы и её дочерних элементов.

Форма по умолчанию отправляет POST-запрос, если объект не сохранён; наоборот, если объект сохранён, он отправит PATCH-запрос. Чтобы указать другой HTTP-глагол, используйте параметр :method в html_options.

Если HTML-кнопка, сгенерированная из button_to, не работает с вашей макетом, вы можете рассмотреть использование метода link_to с атрибутом data-turbo-method, как описано в документации link_to.

Параметры

Хэш options принимает те же параметры, что и url_for. Чтобы сгенерировать элемент <form> без атрибута [action], передайте false:

<%= button_to "New", false %>
# => "<form method="post" class="button_to">
#      <button type="submit">New</button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
#    </form>"

Большинство значений в html_options передаются в элемент кнопки, но есть несколько специальных параметров:

  • :method - Символ HTTP-глагола. Поддерживаемые глаголы - :post, :get, :delete, :patch, и :put. По умолчанию он будет :post.

  • :disabled - Если установлено в true, генерируется отключенная кнопка.

  • :data - Этот параметр можно использовать для добавления пользовательских атрибутов данных.

  • :form - Этот хэш будет атрибутами формы.

  • :form_class - Этот параметр определяет класс формы, в которую будет помещена кнопка отправки.

  • :params - Хэш параметров, которые будут отображаться как скрытые поля в форме.

Примеры

<%= button_to "New", action: "new" %>
# => "<form method="post" action="/controller/new" class="button_to">
#      <button type="submit">New</button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
#    </form>"

<%= button_to "New", new_article_path %>
# => "<form method="post" action="/articles/new" class="button_to">
#      <button type="submit">New</button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
#    </form>"

<%= button_to "New", new_article_path, params: { time: Time.now  } %>
# => "<form method="post" action="/articles/new" class="button_to">
#      <button type="submit">New</button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
#      <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500" autocomplete="off">
#    </form>"

<%= button_to [:make_happy, @user] do %>
  Make happy <strong><%= @user.name %></strong>
<% end %>
# => "<form method="post" action="/users/1/make_happy" class="button_to">
#      <button type="submit">
#        Make happy <strong><%= @user.name %></strong>
#      </button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"  autocomplete="off"/>
#    </form>"

<%= button_to "New", { action: "new" }, form_class: "new-thing" %>
# => "<form method="post" action="/controller/new" class="new-thing">
#      <button type="submit">New</button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"  autocomplete="off"/>
#    </form>"

<%= button_to "Create", { action: "create" }, form: { "data-type" => "json" } %>
# => "<form method="post" action="/images/create" class="button_to" data-type="json">
#      <button type="submit">Create</button>
#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"  autocomplete="off"/>
#    </form>"
current_page?(options = nil, check_parameters: false, **options_as_kwargs) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 548
def current_page?(options = nil, check_parameters: false, **options_as_kwargs)
  unless request
    raise "You cannot use helpers that need to determine the current " \
          "page unless your view context provides a Request object " \
          "in a #request method"
  end

  return false unless request.get? || request.head?

  options ||= options_as_kwargs
  check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
  url_string = URI::RFC2396_PARSER.unescape(url_for(options)).force_encoding(Encoding::BINARY)

  # We ignore any extra parameters in the request_uri if the
  # submitted URL doesn't have any either. This lets the function
  # work with things like ?order=asc
  # the behavior can be disabled with check_parameters: true
  request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
  request_uri = URI::RFC2396_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)

  if %r{^\w+://}.match?(url_string)
    request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
  end

  remove_trailing_slash!(url_string)
  remove_trailing_slash!(request_uri)

  url_string == request_uri
end

True, если текущий URI запроса был сгенерирован заданным options.

Примеры

Предположим, мы находимся в действии http://www.example.com/shop/checkout?order=desc&page=1.

current_page?(action: 'process')
# => false

current_page?(action: 'checkout')
# => true

current_page?(controller: 'library', action: 'checkout')
# => false

current_page?(controller: 'shop', action: 'checkout')
# => true

current_page?(controller: 'shop', action: 'checkout', order: 'asc')
# => false

current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1')
# => true

current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2')
# => false

current_page?('http://www.example.com/shop/checkout')
# => true

current_page?('http://www.example.com/shop/checkout', check_parameters: true)
# => false

current_page?('/shop/checkout')
# => true

current_page?('http://www.example.com/shop/checkout?order=desc&page=1')
# => true

Предположим, мы находимся в действии http://www.example.com/products с методом POST в случае невалидного продукта.

current_page?(controller: 'product', action: 'index')
# => false

Мы также можем передать символические аргументы вместо строк.

link_to(name = nil, options = nil, html_options = nil, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 198
def link_to(name = nil, options = nil, html_options = nil, &block)
  html_options, options, name = options, name, block if block_given?
  options ||= {}

  html_options = convert_options_to_data_attributes(options, html_options)

  url = url_target(name, options)
  html_options["href"] ||= url

  content_tag("a", name || url, html_options, &block)
end

Создаёт элемент якоря с заданным name используя URL, созданный набором options. Смотрите допустимые параметры в документации для url_for. Также можно передать строку вместо хэша параметров, что создаёт элемент якоря, использующий значение строки в качестве href ссылки. Использование символического :back вместо хэша параметров сгенерирует ссылку на referrer (JavaScript back link будет использован вместо referrer, если он не существует). Если nil передаётся в качестве имени, значение самой ссылки станет именем.

Подписи

link_to(body, url, html_options = {})
  # url is a String; you can use URL helpers like
  # posts_path

link_to(body, url_options = {}, html_options = {})
  # url_options, except :method, is passed to url_for

link_to(options = {}, html_options = {}) do
  # name
end

link_to(url, html_options = {}) do
  # name
end

link_to(active_record_model)

Параметры

  • :data - Этот параметр можно использовать для добавления пользовательских атрибутов данных.

Примеры

Поскольку она полагается на url_for, link_to поддерживает как старые аргументы контроллер/действие/id, так и новые RESTful маршруты. Текущий стиль Rails отдаёт предпочтение RESTful маршрутам, когда это возможно, поэтому используйте базовые ресурсы и

link_to "Profile", profile_path(@profile)
# => <a href="/profiles/1">Profile</a>

или даже более краткое

link_to "Profile", @profile
# => <a href="/profiles/1">Profile</a>

вместо более длинного, устаревшего, не ориентированного на ресурсы

link_to "Profile", controller: "profiles", action: "show", id: @profile
# => <a href="/profiles/show/1">Profile</a>

Аналогично,

link_to "Profiles", profiles_path
# => <a href="/profiles">Profiles</a>

лучше чем

link_to "Profiles", controller: "profiles"
# => <a href="/profiles">Profiles</a>

Когда имя - nil, отображается href вместо него

link_to nil, "http://example.com"
# => <a href="http://www.example.com">http://www.example.com</a>

Более лаконично, когда name является моделью Active Record, которая определяет метод to_s возвращающий значение по умолчанию или атрибут модели экземпляра

link_to @profile
# => <a href="http://www.example.com/profiles/1">Eileen</a>

Вы также можете использовать блок, если цель ссылки трудно вписать в параметр имени. ERB пример:

<%= link_to(@profile) do %>
  <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
<% end %>
# => <a href="/profiles/1">
       <strong>David</strong> -- <span>Check it out!</span>
     </a>

Классы и id для CSS легко создать:

link_to "Articles", articles_path, id: "news", class: "article"
# => <a href="/articles" class="article" id="news">Articles</a>

Будьте осторожны при использовании устаревшего стиля аргументов, поскольку требуется дополнительный буквальный хэш:

link_to "Articles", { controller: "articles" }, id: "news", class: "article"
# => <a href="/articles" class="article" id="news">Articles</a>

Если опустить хэш, получится неверная ссылка:

link_to "WRONG!", controller: "articles", id: "news", class: "article"
# => <a href="/articles/index/news?class=article">WRONG!</a>

link_to также может создавать ссылки с анкорами или параметрами запроса:

link_to "Comment wall", profile_path(@profile, anchor: "wall")
# => <a href="/profiles/1#wall">Comment wall</a>

link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails"
# => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>

link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
# => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>

Вы можете установить любые атрибуты ссылки, такие как target, rel, type:

link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
# => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>

Turbo

Rails 7 поставляется с включённой по умолчанию поддержкой Turbo. Turbo предоставляет следующие :data параметры:

  • turbo_method: symbol of HTTP verb - Выполняет посещение Turbo с заданным HTTP-глаголом. Рекомендуется использовать формы при выполнении запросов, отличных от GET. Используйте data-turbo-method только в тех случаях, когда форма невозможна.

  • turbo_confirm: "question?" - Добавляет диалог подтверждения к ссылке со значением.

Обратитесь к Руководству по Turbo, чтобы получить дополнительную информацию об указанных параметрах.

Примеры
link_to "Delete profile", @profile, data: { turbo_method: :delete }
# => <a href="/profiles/1" data-turbo-method="delete">Delete profile</a>

link_to "Visit Other Site", "https://rubyonrails.org/", data: { turbo_confirm: "Are you sure?" }
# => <a href="https://rubyonrails.org/" data-turbo-confirm="Are you sure?">Visit Other Site</a>
link_to_if(condition, name, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 437
def link_to_if(condition, name, options = {}, html_options = {}, &block)
  if condition
    link_to(name, options, html_options)
  else
    if block_given?
      block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
    else
      ERB::Util.html_escape(name)
    end
  end
end

Создаёт тег ссылки с заданным name используя URL, созданный набором options если condition равно true, иначе возвращается только имя. Для специализации поведения по умолчанию можно передать блок, который принимает имя или весь список аргументов для link_to_if.

Примеры

<%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
# If the user isn't logged in...
# => <a href="/sessions/new/">Login</a>

<%=
   link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
     link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
   end
%>
# If the user isn't logged in...
# => <a href="/sessions/new/">Login</a>
# If they are logged in...
# => <a href="/accounts/show/3">my_username</a>
link_to_unless(condition, name, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 414
def link_to_unless(condition, name, options = {}, html_options = {}, &block)
  link_to_if !condition, name, options, html_options, &block
end

Создаёт тег ссылки с заданным name используя URL, созданный набором options если condition не равно true, в противном случае возвращается только имя. Чтобы специализировать поведение по умолчанию (например, отображать ссылку входа вместо просто текста ссылки), можно передать блок, который принимает имя или весь список аргументов для link_to_unless.

Примеры

<%= link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) %>
# If the user is logged in...
# => <a href="/controller/reply/">Reply</a>

<%=
   link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) do |name|
     link_to(name, { controller: "accounts", action: "signup" })
   end
%>
# If the user is logged in...
# => <a href="/controller/reply/">Reply</a>
# If not...
# => <a href="/accounts/signup">Reply</a>
link_to_unless_current(name, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 390
def link_to_unless_current(name, options = {}, html_options = {}, &block)
  link_to_unless current_page?(options), name, options, html_options, &block
end

Создаёт тег ссылки с заданным name используя URL, созданный набором options если текущий URI запроса отличается от ссылок, в противном случае возвращается только имя (или указанный блок, если он существует). Вы можете передать link_to_unless_current блок, который специализирует поведение по умолчанию (например, отображать ссылку «Начать здесь» вместо текста ссылки).

Примеры

Предположим, у вас есть навигационное меню…

<ul id="navbar">
  <li><%= link_to_unless_current("Home", { action: "index" }) %></li>
  <li><%= link_to_unless_current("About Us", { action: "about" }) %></li>
</ul>

Если мы находимся в действии «о нас», отобразится…

<ul id="navbar">
  <li><a href="/controller/index">Home</a></li>
  <li>About Us</li>
</ul>

…но если в действии «индекс», отобразится:

<ul id="navbar">
  <li>Home</li>
  <li><a href="/controller/about">About Us</a></li>
</ul>

Неявный блок, переданный link_to_unless_current оценивается, если текущее действие совпадает с заданным действием. Так, если у нас есть страница комментариев и мы хотим отобразить ссылку «Назад», вместо ссылки на страницу комментариев, мы можем сделать что-то вроде этого…

<%=
    link_to_unless_current("Comment", { controller: "comments", action: "new" }) do
       link_to("Go back", { controller: "posts", action: "index" })
    end
 %>
mail_to(email_address, name = nil, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 487
def mail_to(email_address, name = nil, html_options = {}, &block)
  html_options, name = name, nil if name.is_a?(Hash)
  html_options = (html_options || {}).stringify_keys

  extras = %w{ cc bcc body subject reply_to }.map! { |item|
    option = html_options.delete(item).presence || next
    "#{item.dasherize}=#{ERB::Util.url_encode(option)}"
  }.compact
  extras = extras.empty? ? "" : "?" + extras.join("&")

  encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
  html_options["href"] = "mailto:#{encoded_email_address}#{extras}"

  content_tag("a", name || email_address, html_options, &block)
end

Создаёт тег ссылки mailto для указанного email_address, который также используется в качестве имени ссылки, если не указан name. Дополнительные атрибуты HTML для ссылки можно передать в html_options.

mail_to имеет несколько методов для настройки самого письма путём передачи специальных ключей в html_options.

Параметры

  • :subject - Установка темы письма.

  • :body - Установка тела письма.

  • :cc - Добавление дополнительных получателей в поле Копия.

  • :bcc - Добавление дополнительных получателей в поле Скрытая копия.

  • :reply_to - Установка поля Reply-To письма.

Защита от сбора адресов

До Rails 4.0 mail_to предоставлял параметры для кодирования адреса, чтобы затруднить сбор электронных адресов. Чтобы воспользоваться этими параметрами, установите gem actionview-encoded_mail_to.

Примеры

mail_to "me@domain.com"
# => <a href="mailto:me@domain.com">me@domain.com</a>

mail_to "me@domain.com", "My email"
# => <a href="mailto:me@domain.com">My email</a>

mail_to "me@domain.com", cc: "ccaddress@domain.com",
         subject: "This is an example email"
# => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">me@domain.com</a>

Можно использовать блок, если ссылка сложна для отображения в параметре имени. ERB пример:

<%= mail_to "me@domain.com" do %>
  <strong>Email me:</strong> <span>me@domain.com</span>
<% end %>
# => <a href="mailto:me@domain.com">
       <strong>Email me:</strong> <span>me@domain.com</span>
     </a>
phone_to(phone_number, name = nil, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 669
def phone_to(phone_number, name = nil, html_options = {}, &block)
  html_options, name = name, nil if name.is_a?(Hash)
  html_options = (html_options || {}).stringify_keys

  country_code = html_options.delete("country_code").presence
  country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}"

  encoded_phone_number = ERB::Util.url_encode(phone_number)
  html_options["href"] = "tel:#{country_code}#{encoded_phone_number}"

  content_tag("a", name || phone_number, html_options, &block)
end

Создаёт тег ссылки TEL для указанного phone_number. При нажатии ссылки открывается приложение для совершения звонков и предварительно заполняется номер телефона.

Если name не указан, то phone_number используется в качестве имени ссылки.

Поддерживается параметр country_code, который добавляет знак «плюс» и указанный код страны к номеру телефона. Например, country_code: "01" добавит +01 к номеру телефона.

Дополнительные атрибуты HTML для ссылки можно передать через html_options.

Параметры

  • :country_code - Добавляет код страны к номеру телефона

Примеры

phone_to "1234567890"
# => <a href="tel:1234567890">1234567890</a>

phone_to "1234567890", "Phone me"
# => <a href="tel:1234567890">Phone me</a>

phone_to "1234567890", country_code: "01"
# => <a href="tel:+011234567890">1234567890</a>

Можно использовать блок, если ссылка сложна для отображения в параметре имени. Пример с ERB:

<%= phone_to "1234567890" do %>
  <strong>Phone me:</strong>
<% end %>
# => <a href="tel:1234567890">
       <strong>Phone me:</strong>
     </a>
sms_to(phone_number, name = nil, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/url_helper.rb, line 618
def sms_to(phone_number, name = nil, html_options = {}, &block)
  html_options, name = name, nil if name.is_a?(Hash)
  html_options = (html_options || {}).stringify_keys

  country_code = html_options.delete("country_code").presence
  country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : ""

  body = html_options.delete("body").presence
  body = body ? "?&body=#{ERB::Util.url_encode(body)}" : ""

  encoded_phone_number = ERB::Util.url_encode(phone_number)
  html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"

  content_tag("a", name || phone_number, html_options, &block)
end

Создаёт тег ссылки SMS для указанного phone_number. При нажатии ссылки открывается приложение для отправки SMS, готовое отправить сообщение на указанный номер телефона. Если указан параметр body, содержимое сообщения будет установлено в body.

Если name не указан, то phone_number используется в качестве имени ссылки.

Поддерживается параметр country_code, который добавляет знак «плюс» и указанный код страны к номеру телефона. Например, country_code: "01" добавит +01 к номеру телефона.

Дополнительные атрибуты HTML для ссылки можно передать через html_options.

Параметры

  • :country_code - Добавить код страны к номеру телефона.

  • :body - Установить содержимое сообщения.

Примеры

sms_to "5155555785"
# => <a href="sms:5155555785;">5155555785</a>

sms_to "5155555785", country_code: "01"
# => <a href="sms:+015155555785;">5155555785</a>

sms_to "5155555785", "Text me"
# => <a href="sms:5155555785;">Text me</a>

sms_to "5155555785", body: "I have a question about your product."
# => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>

Можно использовать блок, если ссылка сложна для отображения в параметре имени. Пример с ERB:

<%= sms_to "5155555785" do %>
  <strong>Text me:</strong>
<% end %>
# => <a href="sms:5155555785;">
       <strong>Text me:</strong>
     </a>

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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