Spec-Zone.ru › Ruby on Rails 8.0

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

Включённые модули:
ActionView::Helpers::FormTagHelper, ActionView::Helpers::UrlHelper, ActionView::RecordIdentifier

Справочные инструменты Action View для форм

Справочные инструменты для форм предназначены для упрощения работы с ресурсами по сравнению с использованием обычного HTML.

Обычно форма, предназначенная для создания или обновления ресурса, отражает идентификацию ресурса несколькими способами: (i) URL, к которому отправляется форма (атрибут элемента формы action) должен привести к маршрутизации запроса к соответствующему действию контроллера (с соответствующим параметром :id в случае существующего ресурса), (ii) имена полей ввода должны быть такими, чтобы в контроллере их значения отображались в соответствующих местах в хэше params, и (iii) для существующего ресурса, когда форма первоначально отображается, поля ввода, соответствующие атрибутам ресурса, должны отображать текущие значения этих атрибутов.

В Rails это обычно достигается путём создания формы с помощью form_with или form_for и ряда связанных вспомогательных методов. Эти методы генерируют соответствующий тег form и возвращают объект генератора формы, который знает модель, к которой относится форма. Поля ввода создаются путём вызова методов, определённых в генераторе формы, что позволяет генерировать соответствующие имена и значения по умолчанию, соответствующие атрибутам модели, а также удобные идентификаторы и т. д. Конвенции в сгенерированных именах полей позволяют контроллерам получать данные формы в виде красиво структурированного хэша params без каких-либо усилий с вашей стороны.

Например, для создания новой персоны вы обычно создаёте новый экземпляр Person в действии PeopleController#new, @person, и во шаблоне представления передаёте этот объект в form_with или form_for:

<%= form_with model: @person do |f| %>
  <%= f.label :first_name %>:
  <%= f.text_field :first_name %><br />

  <%= f.label :last_name %>:
  <%= f.text_field :last_name %><br />

  <%= f.submit %>
<% end %>

Сгенерированный HTML для этого будет (с учётом форматирования):

<form action="/people" class="new_person" id="new_person" method="post">
  <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
  <label for="person_first_name">First name</label>:
  <input id="person_first_name" name="person[first_name]" type="text" /><br />

  <label for="person_last_name">Last name</label>:
  <input id="person_last_name" name="person[last_name]" type="text" /><br />

  <input name="commit" type="submit" value="Create Person" />
</form>

Как вы видите, HTML отражает знания о ресурсе в нескольких местах, таких как путь, по которому должна отправляться форма, или имена полей ввода.

В частности, благодаря соглашениям, используемым в сгенерированных именах полей, контроллер получает вложенный хэш params[:person] с атрибутами персоны, заданными в форме. Этот хэш готов к передаче в Person.new:

@person = Person.new(params[:person])
if @person.save
  # success
else
  # error handling
end

Интересно, что тот же код представления в предыдущем примере можно использовать для редактирования персоны. Если @person является существующим ресурсом с именем «Иван Иванов» и ID 256, вышеприведённый код выдаст:

<form action="/people/256" class="edit_person" id="edit_person_256" method="post">
  <input name="_method" type="hidden" value="patch" />
  <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
  <label for="person_first_name">First name</label>:
  <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br />

  <label for="person_last_name">Last name</label>:
  <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br />

  <input name="commit" type="submit" value="Update Person" />
</form>

Обратите внимание, что конечная точка, значения по умолчанию и метка кнопки отправки настроены для @person. Это работает таким образом, потому что используемые вспомогательные методы знают, является ли ресурс новой записью или нет, и генерируют HTML соответственно.

Контроллер снова получит данные формы в params[:person], готовые к передаче в Person#update:

if @person.update(params[:person])
  # success
else
  # error handling
end

Вот как обычно работают с ресурсами.

Публичные методы экземпляров

check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Псевдоним для: checkbox
checkbox(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1347
def checkbox(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
  Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render
end

Возвращает тег checkbox, настроенный для доступа к указанному атрибуту (определяемому method) объекта, назначенного шаблону (определяемому object). Этот объект должен быть экземпляром объекта (@object), а не локальным объектом. Ожидается, что method вернёт целое число, и если это целое число больше нуля, то checkbox будет отмечен. Дополнительные параметры тега input могут быть переданы в виде хэша с options. Значение checked_value по умолчанию равно 1, а значение по умолчанию unchecked_value установлено в 0, что удобно для булевых значений.

Параметры

  • Любые стандартные атрибуты HTML для тега могут быть переданы, например :class.

  • :checked - true или false принудительно устанавливает состояние checkbox в отмеченное или не отмеченное.

  • :include_hidden - Если установлено в false, вспомогательное скрытое поле, описанное ниже, не будет сгенерировано.

Особенности

Спецификация HTML гласит, что неотмеченные checkbox не отправляются, и поэтому веб-браузеры их не отправляют. К сожалению, это приводит к проблеме: если у модели Invoice установлен флаг paid, и в форме редактирования платного счета пользователь сбросил checkbox, параметр paid не отправляется. Таким образом, любое выражение массового присваивания, например

@invoice.update(params[:invoice])

не обновит флаг.

Для предотвращения этого, помощник генерирует вспомогательное скрытое поле перед каждым checkbox. Скрытое поле имеет то же имя, а его атрибуты имитируют неотмеченный checkbox.

Таким образом, клиент отправляет либо только скрытое поле (что указывает на то, что checkbox не отмечен), либо оба поля. Поскольку спецификация HTML гласит, что пары ключ/значение должны отправляться в том же порядке, в котором они появляются в форме, а извлечение параметров получает последнюю встречаемость любого повторяющегося ключа в строке запроса, это работает для обычных форм.

К сожалению, этот обходной путь не работает, когда checkbox находится внутри массивоподобного параметра, как в

<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
  <%= form.checkbox :paid %>
  ...
<% end %>

потому что повторение имён параметров именно то, что Rails пытается различить элементы массива. Для каждого элемента с отмеченным checkbox вы получаете дополнительный "фантомный" элемент только с этим атрибутом, назначенным в «0».

В этом случае предпочтительно использовать checkbox_tag или использовать хэши вместо массивов.

Примеры

# Let's say that @article.validated? is 1:
checkbox("article", "validated")
# => <input name="article[validated]" type="hidden" value="0" />
#    <input checked="checked" type="checkbox" id="article_validated" name="article[validated]" value="1" />

# Let's say that @puppy.gooddog is "no":
checkbox("puppy", "gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
#    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />

checkbox("eula", "accepted", { class: 'eula_check' }, "yes", "no")
# => <input name="eula[accepted]" type="hidden" value="no" />
#    <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
Также алиас для: check_box
color_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1378
def color_field(object_name, method, options = {})
  Tags::ColorField.new(object_name, method, self, options).render
end

Возвращает text_field типа “color”.

color_field("car", "color")
# => <input id="car_color" name="car[color]" type="color" value="#000000" />
date_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1442
def date_field(object_name, method, options = {})
  Tags::DateField.new(object_name, method, self, options).render
end

Возвращает text_field типа “date”.

date_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" />

Значение по умолчанию генерируется, пытаясь вызвать strftime с «%Y-%m-%d» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone. Вы можете переопределить это, явно передав параметр «value», например:

@user.born_on = Date.new(1984, 1, 27)
date_field("user", "born_on", value: "1984-05-12")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />

Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.

date_field("user", "born_on", min: Date.today)
# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />

В качестве альтернативы, вы можете передать String, отформатированный как дата ISO8601, в качестве значений для «min» и «max».

date_field("user", "born_on", min: "2014-05-20")
# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
datetime_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1515
def datetime_field(object_name, method, options = {})
  Tags::DatetimeLocalField.new(object_name, method, self, options).render
end

Возвращает text_field типа “datetime-local”.

datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" />

Значение по умолчанию генерируется, пытаясь вызвать strftime с «%Y-%m-%dT%T» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.

@user.born_on = Date.new(1984, 1, 12)
datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />

Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.

datetime_field("user", "born_on", min: Date.today)
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />

В качестве альтернативы, вы можете передать String, отформатированный как дата-время ISO8601, в качестве значений для «min» и «max».

datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />

По умолчанию, предоставляемые значения даты и времени будут отформатированы, включая секунды. Вы можете отобразить только дату, час и минуту, передав include_seconds: false.

@user.born_on = Time.current
datetime_field("user", "born_on", include_seconds: false)
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
Также алиас для: datetime_local_field
datetime_local_field(object_name, method, options = {})
Псевдоним для: datetime_field
email_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1569
def email_field(object_name, method, options = {})
  Tags::EmailField.new(object_name, method, self, options).render
end

Возвращает text_field типа “email”.

email_field("user", "address")
# => <input id="user_address" name="user[address]" type="email" />
fields(scope = nil, model: nil, **options, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1080
def fields(scope = nil, model: nil, **options, &block)
  options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)

  if model
    model   = _object_for_form_builder(model)
    scope ||= model_name_from_record_or_class(model).param_key
  end

  builder = instantiate_builder(scope, model, options)
  capture(builder, &block)
end

Ограничивает поля ввода с помощью явного ограничения или модели. Подобно тому, как form_with делает это с :scope или :model, за исключением того, что не выводит теги формы.

# Using a scope prefixes the input field names:
<%= fields :comment do |fields| %>
  <%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]">

# Using a model infers the scope and assigns field values:
<%= fields model: Comment.new(body: "full bodied") do |fields| %>
  <%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]" value="full bodied">

# Using +fields+ with +form_with+:
<%= form_with model: @article do |form| %>
  <%= form.text_field :title %>

  <%= form.fields :comment do |fields| %>
    <%= fields.text_field :body %>
  <% end %>
<% end %>

Подобно form_with, передаётся экземпляр FormBuilder, связанный с ограничением или моделью, так что все сгенерированные имена полей имеют префикс, либо с переданным ограничением, либо с ограничением, полученным из :model.

Смешивание с другими помощниками форм

Хотя form_with использует объект FormBuilder, можно смешивать и сочетать автономные методы FormHelper и методы из FormTagHelper:

<%= fields model: @comment do |fields| %>
  <%= fields.text_field :body %>

  <%= textarea :commenter, :biography %>
  <%= checkbox_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %>
<% end %>

То же самое относится к методам в FormOptionsHelper и DateHelper, предназначенным для работы с объектом в качестве базы, например, FormOptionsHelper#collection_select и DateHelper#datetime_select.

fields_for(record_name, record_object = nil, options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1029
def fields_for(record_name, record_object = nil, options = {}, &block)
  options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options)

  fields(record_name, **options, &block)
end

Создаёт область действия вокруг определённого объекта модели, например form_with, но не создаёт сами теги формы. Это делает fields_for подходящим для указания дополнительных объектов модели в той же форме.

Хотя использование и назначение fields_for аналогично form_with‘s, его сигнатура метода немного отличается. Как и form_with, он передаёт объект FormBuilder, связанный с конкретным объектом модели, в блок, и внутри блока можно вызывать методы для генерации полей, связанных с объектом модели. Поля могут отражать объект модели двумя способами — как они названы (а значит, как представлено значение отправки в хэше params в контроллере) и какие значения по умолчанию отображаются при первом отображении полей формы. Для того, чтобы оба этих параметра можно было указать независимо, можно передать в метод отдельно как имя объекта (представленное символом или строкой), так и сам объект —

<%= form_with model: @person do |person_form| %>
  First name: <%= person_form.text_field :first_name %>
  Last name : <%= person_form.text_field :last_name %>

  <%= fields_for :permission, @person.permission do |permission_fields| %>
    Admin?  : <%= permission_fields.checkbox :admin %>
  <% end %>

  <%= person_form.submit %>
<% end %>

В этом случае поле флажка будет представлено HTML-тегом input с атрибутом name permission[admin], и переданное значение будет отображаться в контроллере как params[:permission][:admin]. Если @person.permission — это существующий объект с атрибутом admin, начальное состояние флажка при первом отображении будет отражать значение @person.permission.admin.

Часто это можно упростить, передав просто имя объекта модели в fields_for —

<%= fields_for :permission do |permission_fields| %>
  Admin?: <%= permission_fields.checkbox :admin %>
<% end %>

…в этом случае, если :permission также является именем переменной экземпляра @permission, начальное состояние поля ввода будет отражать значение атрибута этой переменной @permission.admin.

В качестве альтернативы, вы можете передать только сам объект модели (если первый аргумент не является строкой или символом fields_for, fields_for поймёт, что имя опущено) —

<%= fields_for @person.permission do |permission_fields| %>
  Admin?: <%= permission_fields.checkbox :admin %>
<% end %>

и fields_for определит необходимое имя поля из класса объекта модели, например, если @person.permission, относится к классу Permission, поле всё равно будет называться permission[admin].

Примечание: Это также работает для методов в FormOptionsHelper и DateHelper, которые разработаны для работы с объектом в качестве базы, например FormOptionsHelper#collection_select и DateHelper#datetime_select.

Примеры вложенных атрибутов

Когда объект, относящийся к текущей области действия, имеет метод-запись вложенного атрибута для определённого атрибута, fields_for создаст новую область действия для этого атрибута. Это позволяет создавать формы, которые устанавливают или изменяют атрибуты родительского объекта и его ассоциаций в один приём.

Методы записи вложенных атрибутов — это обычные методы записи, названные по имени ассоциации. Наиболее распространённый способ определения этих методов записи — с помощью accepts_nested_attributes_for в определении модели или путём определения метода с соответствующим именем. Например: метод записи атрибута для ассоциации :address называется address_attributes=.

Будет ли создан экземпляр формы для одного к одному или для одного ко многим, зависит от того, возвращает ли обычный метод чтения один объект или массив объектов.

Один к одному

Рассмотрим класс Person, который возвращает один Address из метода чтения address и отвечает на метод записи address_attributes=:

class Person
  def address
    @address
  end

  def address_attributes=(attributes)
    # Process the attributes hash
  end
end

Теперь эта модель может быть использована с вложенным fields_for, например так:

<%= form_with model: @person do |person_form| %>
  ...
  <%= person_form.fields_for :address do |address_fields| %>
    Street  : <%= address_fields.text_field :street %>
    Zip code: <%= address_fields.text_field :zip_code %>
  <% end %>
  ...
<% end %>

Если адрес уже является ассоциацией Person, можно использовать accepts_nested_attributes_for для определения метода записи за вас:

class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
end

Если нужно удалить связанную модель через форму, нужно сначала включить это с помощью параметра :allow_destroy для accepts_nested_attributes_for:

class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address, allow_destroy: true
end

Теперь, когда вы используете элемент формы с параметром _destroy со значением, которое вычисляется как true, вы удалите связанную модель (например, 1, ‘1’, true или ‘true’):

<%= form_with model: @person do |person_form| %>
  ...
  <%= person_form.fields_for :address do |address_fields| %>
    ...
    Delete: <%= address_fields.checkbox :_destroy %>
  <% end %>
  ...
<% end %>

Один ко многим

Рассмотрим класс Person, который возвращает массив экземпляров Project из метода чтения projects и отвечает на метод записи projects_attributes=:

class Person
  def projects
    [@project1, @project2]
  end

  def projects_attributes=(attributes)
    # Process the attributes hash
  end
end

Обратите внимание, что метод записи projects_attributes= фактически необходим для fields_for, чтобы правильно идентифицировать :projects как коллекцию и установить правильные индексы в разметке формы.

Если projects уже является ассоциацией Person, можно использовать accepts_nested_attributes_for для определения метода записи за вас:

class Person < ActiveRecord::Base
  has_many :projects
  accepts_nested_attributes_for :projects
end

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

<%= form_with model: @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    <% if project_fields.object.active? %>
      Name: <%= project_fields.text_field :name %>
    <% end %>
  <% end %>
  ...
<% end %>

Также можно указать используемый экземпляр:

<%= form_with model: @person do |person_form| %>
  ...
  <% @person.projects.each do |project| %>
    <% if project.active? %>
      <%= person_form.fields_for :projects, project do |project_fields| %>
        Name: <%= project_fields.text_field :name %>
      <% end %>
    <% end %>
  <% end %>
  ...
<% end %>

Или коллекцию:

<%= form_with model: @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
    Name: <%= project_fields.text_field :name %>
  <% end %>
  ...
<% end %>

Если нужно удалить связанные модели через форму, нужно сначала включить это с помощью параметра :allow_destroy для accepts_nested_attributes_for:

class Person < ActiveRecord::Base
  has_many :projects
  accepts_nested_attributes_for :projects, allow_destroy: true
end

Это позволит указать, какие модели нужно удалить в хэше атрибутов, добавив элемент формы для параметра _destroy со значением, которое вычисляется как true (например, 1, ‘1’, true или ‘true’):

<%= form_with model: @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    Delete: <%= project_fields.checkbox :_destroy %>
  <% end %>
  ...
<% end %>

Когда используется коллекция, возможно, вам понадобится знать индекс каждого объекта в массиве. Для этого доступен метод index в объекте FormBuilder.

<%= form_with model: @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    Project #<%= project_fields.index %>
    ...
  <% end %>
  ...
<% end %>

Обратите внимание, что fields_for автоматически сгенерирует скрытое поле для хранения идентификатора записи, если оно отвечает методу persisted?. В некоторых случаях это скрытое поле не нужно, и вы можете передать include_id: false для предотвращения автоматического рендеринга fields_for.

file_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1248
def file_field(object_name, method, options = {})
  options = { include_hidden: multiple_file_field_include_hidden }.merge!(options)

  Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
end

Возвращает тег ввода для загрузки файлов, настроенный для доступа к указанному атрибуту (определённому method) объекта, назначенного шаблону (определённого object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибут HTML-элемента, как показано в примере.

Использование этого метода внутри блока form_with установит кодировку окружающего элемента формы на multipart/form-data.

Параметры

  • Создаёт стандартные атрибуты HTML для тега.

  • :disabled — Если установлено в true, пользователь не сможет использовать этот элемент ввода.

  • :multiple — Если установлено в true, *в большинстве современных браузеров* пользователь сможет выбрать несколько файлов.

  • :include_hidden — Когда multiple: true и include_hidden: true, поле будет префиксным полем <input type="hidden"> со значением по умолчанию, чтобы поддерживать отправку пустой коллекции файлов.

  • :accept — Если установлено на один или несколько MIME-типов, пользователю будет предложен фильтр при выборе файла. Вам всё равно необходимо настроить валидацию модели.

Примеры

file_field(:user, :avatar)
# => <input type="file" id="user_avatar" name="user[avatar]" />

file_field(:article, :image, multiple: true)
# => <input type="file" id="article_image" name="article[image][]" multiple="multiple" />

file_field(:article, :attached, accept: 'text/html')
# => <input accept="text/html" type="file" id="article_attached" name="article[attached]" />

file_field(:article, :image, accept: 'image/png,image/gif,image/jpeg')
# => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" />

file_field(:attachment, :file, class: 'file_input')
# => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
form_for(record, options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 436
def form_for(record, options = {}, &block)
  raise ArgumentError, "Missing block" unless block_given?

  case record
  when String, Symbol
    model       = false
    object_name = record
  else
    model       = record
    object      = _object_for_form_builder(record)
    raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
    object_name = options[:as] || model_name_from_record_or_class(object).param_key
    apply_form_for_options!(object, options)
  end

  remote = options.delete(:remote)

  if remote && !embed_authenticity_token_in_remote_forms && options[:authenticity_token].blank?
    options[:authenticity_token] = false
  end

  options[:model]                               = model
  options[:scope]                               = object_name
  options[:local]                               = !remote
  options[:skip_default_ids]                    = false
  options[:allow_method_names_outside_object]   = options.fetch(:allow_method_names_outside_object, false)

  form_with(**options, &block)
end

Создаёт форму, позволяющую пользователю создавать или обновлять атрибуты конкретного объекта модели.

Метод может использоваться несколькими немного разными способами, в зависимости от того, насколько вы хотите полагаться на Rails для автоматического определения того, как должна быть построена форма. Для общего объекта модели форма может быть создана путём передачи form_for строки или символа, представляющего объект, который нас интересует:

<%= form_for :person do |f| %>
  First name: <%= f.text_field :first_name %><br />
  Last name : <%= f.text_field :last_name %><br />
  Biography : <%= f.textarea :biography %><br />
  Admin?    : <%= f.checkbox :admin %><br />
  <%= f.submit %>
<% end %>

Переменная f передаваемая в блок, является объектом FormBuilder, который содержит знания об объекте модели, представленном :person переданным в form_for. Методы, определенные для FormBuilder, используются для генерации полей, связанных с этой моделью. Таким образом, например,

<%= f.text_field :first_name %>

будет преобразовано в

<%= text_field :person, :first_name %>

что приводит к тегу HTML <input>, атрибут name которого person[first_name]. Это означает, что при отправке формы значение, введенное пользователем, будет доступно в контроллере как params[:person][:first_name].

Для полей, сгенерированных таким образом с помощью FormBuilder, если :person также является именем переменной экземпляра @person, значение по умолчанию для поля, отображаемого при первоначальном отображении формы (например, в ситуации, когда вы редактируете существующий объект), будет значением соответствующего атрибута объекта @person.

Правый аргумент form_for — это необязательный хэш опций:

  • :url — URL, на который должна быть отправлена форма. Он может быть представлен таким же образом, как значения, передаваемые в url_for или link_to. Например, можно напрямую использовать именованный маршрут. Когда модель представляется строкой или символом, как в примере выше, если опция :url не указана, форма по умолчанию отправляется на текущий URL (мы опишем ниже альтернативное использование form_for с ресурсно-ориентированной формой, в которой URL не нужно указывать явно).

  • :namespace — пространство имён для вашей формы, чтобы гарантировать уникальность атрибутов id элементов формы. Атрибут пространства имен будет предваряться символом подчеркивания в сгенерированном HTML id.

  • :method — метод, используемый при отправке формы, обычно «get» или «post». Если используется «patch», «put», «delete» или другой глагол, добавляется скрытый ввод с именем _method, чтобы смоделировать глагол с отправкой POST.

  • :authenticity_token — маркер подлинности для использования в форме. Используйте только если вам нужно передать строку маркера подлинности, или чтобы не добавлять поле authenticity_token вообще (передав false). Дистанционные формы могут опустить встраиваемый маркер подлинности, установив config.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно, когда вы кэшируете форму по фрагментам. Дистанционные формы получают маркер подлинности из тега meta, поэтому встраивание не требуется, если вы поддерживаете браузеры без JavaScript.

  • :remote — если установлено в true, позволит неочевидным драйверам JavaScript управлять поведением отправки.

  • :enforce_utf8 — если установлено в false, скрытый ввод с именем utf8 не выводится.

  • :html — необязательные HTML атрибуты для тега формы.

Также обратите внимание, что form_for не создаёт исключительной области. По-прежнему можно использовать как самостоятельные методы FormHelper, так и методы из FormTagHelper. Например:

<%= form_for :person do |f| %>
  First name: <%= f.text_field :first_name %>
  Last name : <%= f.text_field :last_name %>
  Biography : <%= textarea :person, :biography %>
  Admin?    : <%= checkbox_tag "person[admin]", "1", @person.company.admin? %>
  <%= f.submit %>
<% end %>

Это также работает для методов в FormOptionsHelper и DateHelper, которые разработаны для работы с объектом в качестве основы, например, FormOptionsHelper#collection_select и DateHelper#datetime_select.

form_for с объектом модели

В примерах выше объект для создания или редактирования представлялся символом, переданным в form_for, и мы отметили, что строку также можно использовать аналогично. Однако также возможно передать сам объект модели в form_for. Например, если @article это существующий объект, который вы хотите отредактировать, вы можете создать форму, используя

<%= form_for @article do |f| %>
  ...
<% end %>

Это работает почти так же, как описано ранее, с парой небольших исключений. Во-первых, префикс, используемый для именования элементов ввода в форме (следовательно, ключ, который обозначает их в хеше params), фактически получен из класса объекта, например params[:article], если класс объекта — Article. Однако это можно переопределить, используя опцию :as, например:

<%= form_for(@person, as: :client) do |f| %>
  ...
<% end %>

что приведет к params[:client].

Во-вторых, значения полей, отображаемые при первоначальном отображении формы, берутся из атрибутов объекта, переданного в form_for, независимо от того, является ли объект переменной экземпляра. Например, если у нас есть локальная переменная article, представляющая существующий объект,

<%= form_for article do |f| %>
  ...
<% end %>

произведёт форму с полями, начальное состояние которых отражает текущие значения атрибутов объекта article.

Ресурсно-ориентированный стиль

В только что показанных примерах, хотя и не указано явно, нам всё ещё нужно использовать опцию :url для указания того, куда будет отправлена форма. Однако дальнейшее упрощение возможно, если объект, переданный в form_for, является ресурсом, т.е. он соответствует набору маршрутов RESTful, например, определенных с помощью метода resources в config/routes.rb. В этом случае Rails просто выведет соответствующий URL из самого объекта. Например,

<%= form_for @article do |f| %>
  ...
<% end %>

эквивалентно чему-то вроде:

<%= form_for @article, as: :article, url: article_path(@article), method: :patch, html: { class: "edit_article", id: "edit_article_45" } do |f| %>
  ...
<% end %>

И для нового объекта

<%= form_for(Article.new) do |f| %>
  ...
<% end %>

эквивалентно чему-то вроде:

<%= form_for @article, as: :article, url: articles_path, html: { class: "new_article", id: "new_article" } do |f| %>
  ...
<% end %>

Однако вы всё ещё можете переопределить отдельные соглашения, например:

<%= form_for(@article, url: super_articles_path) do |f| %>
  ...
<% end %>

Вы можете опустить атрибут action передав url: false:

<%= form_for(@article, url: false) do |f| %>
  ...
<% end %>

Вы также можете задать формат ответа, например так:

<%= form_for(@article, format: :json) do |f| %>
  ...
<% end %>

Для маршрутов с именованными пространствами, например admin_article_url:

<%= form_for([:admin, @article]) do |f| %>
 ...
<% end %>

Если у вашего ресурса определены ассоциации, например, вы хотите добавить комментарии к документу, учитывая, что маршруты настроены правильно:

<%= form_for([@document, @comment]) do |f| %>
 ...
<% end %>

Где @document = Document.find(params[:id]) и @comment = Comment.new.

Установка метода

Вы можете принудительно заставить форму использовать полный набор HTTP глаголов, установив

method: (:get|:post|:patch|:put|:delete)

в хэше опций. Если глагол не GET или POST, которые изначально поддерживаются HTML формами, форма будет установлена на POST, а скрытый элемент с именем _method будет содержать предназначенный глагол для интерпретации сервером.

Неочевидный JavaScript

Указание:

remote: true

в хэше опций создаёт форму, которая позволит неочевидным драйверам JavaScript изменять её поведение. Отправка формы будет работать так же, как обычная отправка, как её видит сторона получателя (все элементы доступны в params).

Пример:

<%= form_for(@article, remote: true) do |f| %>
  ...
<% end %>

Сгенерированный для этого HTML будет:

<form action='http://www.example.com' method='post' data-remote='true'>
  <input name='_method' type='hidden' value='patch' />
  ...
</form>

Установка HTML опций

Вы можете установить атрибуты данных напрямую, передав хэш данных, но все остальные HTML опции должны быть обернуты в ключ HTML. Пример:

<%= form_for(@article, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
  ...
<% end %>

Сгенерированный для этого HTML будет:

<form action='http://www.example.com' method='post' data-behavior='autosave' name='go'>
  <input name='_method' type='hidden' value='patch' />
  ...
</form>

Удаление скрытых id модели

Метод form_for автоматически включает id модели как скрытое поле в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют id в вложенных моделях, поэтому в этом случае вам нужно будет отключить скрытый id.

В следующем примере модель статьи имеет много комментариев, хранящихся внутри неё в базе данных NoSQL, поэтому для комментариев нет первичного ключа.

Пример:

<%= form_for(@article) do |f| %>
  <%= f.fields_for(:comments, include_id: false) do |cf| %>
    ...
  <% end %>
<% end %>

Настраиваемые генераторы форм

Вы также можете создавать формы, используя настраиваемый класс FormBuilder. Подклассируйте FormBuilder и переопределите или определите некоторые дополнительные помощники, а затем используйте свой настраиваемый генератор. Например, предположим, что вы создали помощник для автоматического добавления меток к элементам формы.

<%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
  <%= f.text_field :first_name %>
  <%= f.text_field :last_name %>
  <%= f.textarea :biography %>
  <%= f.checkbox :admin %>
  <%= f.submit %>
<% end %>

В этом случае, если вы используете это:

<%= render f %>

Отображаемая в шаблоне форма будет people/_labelling_form, а локальная переменная, ссылающаяся на генератор формы, называется labelling_form.

Настраиваемый класс FormBuilder автоматически объединяется с опциями вложенного вызова fields_for, если не указано явно.

В многих случаях вы захотите обернуть это в другой помощник, поэтому вы можете сделать что-то вроде следующего:

def labelled_form_for(record_or_name_or_array, *args, &block)
  options = args.extract_options!
  form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block)
end

Если вам не нужно привязывать форму к экземпляру модели, ознакомьтесь со статьёй FormTagHelper#form_tag.

Форма для внешних ресурсов

Когда вы создаёте формы для внешних ресурсов, иногда вам нужно установить маркер подлинности или просто отобразить форму без него, например, когда вы отправляете данные на веб-сайт платежной системы, количество и типы полей могут быть ограничены.

Чтобы установить маркер подлинности, вам нужно передать параметр :authenticity_token

<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %>
  ...
<% end %>

Если вы не хотите, чтобы поле маркера подлинности отображалось вообще, просто передайте false:

<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %>
  ...
<% end %>
form_with(model: false, scope: nil, url: nil, format: nil, **options, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 756
def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block)
  raise ArgumentError, "Passed nil to the :model argument, expect an object or false" if model.nil?

  options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)

  if model
    if url != false
      url ||= if format.nil?
        polymorphic_path(model, {})
      else
        polymorphic_path(model, format: format)
      end
    end

    model   = convert_to_model(_object_for_form_builder(model))
    scope ||= model_name_from_record_or_class(model).param_key
  end

  if block_given?
    builder = instantiate_builder(scope, model, options)
    output  = capture(builder, &block)
    options[:multipart] ||= builder.multipart?

    html_options = html_options_for_form_with(url, model, **options)
    form_tag_with_body(html_options, output)
  else
    html_options = html_options_for_form_with(url, model, **options)
    form_tag_html(html_options)
  end
end

Создаёт тег формы, основанный на смешении URL, областей или моделей.

# Using just a URL:
<%= form_with url: articles_path do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/articles" method="post">
  <input type="text" name="title" />
</form>

# With an intentionally empty URL:
<%= form_with url: false do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form method="post">
  <input type="text" name="title" />
</form>

# Adding a scope prefixes the input field names:
<%= form_with scope: :article, url: articles_path do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/articles" method="post">
  <input type="text" name="article[title]" />
</form>

# Using a model infers both the URL and scope:
<%= form_with model: Article.new do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/articles" method="post">
  <input type="text" name="article[title]" />
</form>

# An existing model makes an update form and fills out field values:
<%= form_with model: Article.first do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/articles/1" method="post">
  <input type="hidden" name="_method" value="patch" />
  <input type="text" name="article[title]" value="<the title of the article>" />
</form>
# Though the fields don't have to correspond to model attributes:
<%= form_with model: Cat.new do |form| %>
  <%= form.text_field :cats_dont_have_gills %>
  <%= form.text_field :but_in_forms_they_can %>
<% end %>
# =>
<form action="/cats" method="post">
  <input type="text" name="cat[cats_dont_have_gills]" />
  <input type="text" name="cat[but_in_forms_they_can]" />
</form>

Параметры в формах доступны в контроллерах в соответствии с их вложенностью имён. Таким образом, поля с именами title и article[title] доступны как params[:title] и params[:article][:title] соответственно.

Для простоты сравнения в примерах выше отсутствуют кнопка отправки, а также автоматически сгенерированные скрытые поля, обеспечивающие поддержку UTF-8 и добавляющие маркер аутентичности, необходимый для защиты от межсайтовых запросов.

Ориентированный на ресурсы стиль

Во многих из представленных примеров :model, переданное в form_with — это ресурс. Он соответствует набору маршрутов RESTful, скорее всего, определённых с помощью resources в config/routes.rb.

Поэтому при передаче такой записи модели Rails определяет URL и метод.

<%= form_with model: @article do |form| %>
  ...
<% end %>

тогда эквивалентно примерно такому:

<%= form_with scope: :article, url: article_path(@article), method: :patch do |form| %>
  ...
<% end %>

А для новой записи

<%= form_with model: Article.new do |form| %>
  ...
<% end %>

эквивалентно примерно такому:

<%= form_with scope: :article, url: articles_path do |form| %>
  ...
<% end %>

form_with параметры

  • :url — URL, на который отправляется форма. Аналогично значениям, переданным в url_for или link_to. Например, вы можете напрямую использовать именованный маршрут. Когда :scope передаётся без :url, форма просто отправляется на текущий URL.

  • :method — метод, используемый при отправке формы, обычно «get» или «post». Если «patch», «put», «delete» или другой глагол, добавляется скрытое поле с именем _method, чтобы имитировать глагол через post.

  • :format — формат маршрута, на который отправляется форма. Полезно при отправке на другой тип ресурса, например, :json. Пропускается, если передаётся :url.

  • :scope — область для префикса имён полей ввода, а также для группировки переданных параметров в контроллерах.

  • :namespace — пространство имён для вашей формы, чтобы обеспечить уникальность атрибутов id элементов формы. Атрибут пространства имён будет префиксам в HTML id символом подчёркивания.

  • :model — объект модели для вывода :url и :scope , а также заполнения значений полей ввода. Если title имеет значение «Ahoy!», то значение поля ввода title будет «Ahoy!», Если модель — новая запись, генерируется форма создания, если существующая запись — форма обновления. Передайте :scope или :url для переопределения значений по умолчанию. Например, превратить params[:article] в params[:blog].

  • :authenticity_token — маркер аутентификации для использования в форме. Переопределите пользовательским маркером аутентификации или передайте false для пропуска поля маркера аутентификации. Полезно при отправке на внешний ресурс, например, на платежную шлюз, который может ограничивать допустимые поля. Дистанционные формы могут опустить встроенный маркер аутентификации, установив config.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно при кэшировании фрагментов формы. Дистанционные формы получают маркер аутентификации из тега meta, поэтому вставка не нужна, если вы поддерживаете браузеры без JavaScript.

  • :local — использовать стандартную отправку формы по HTTP. Если значение равно true, форма отправляется по стандартному HTTP. Если значение равно false, форма отправляется как «дистанционная форма», которая обрабатывается Rails UJS как XHR. При отсутствии указания поведение определяется из config.action_view.form_with_generates_remote_forms, где значение конфигурации на самом деле является инверсией значения local. Начиная с Rails 6.1, значение этой опции конфигурации по умолчанию равно false (что эквивалентно передаче local: true). В предыдущих версиях Rails значение этой опции конфигурации по умолчанию равно true (эквивалентно передаче local: false).

  • :skip_enforcing_utf8 — Если установлено в true, скрытое поле с именем utf8 не выводится.

  • :builder — переопределить объект, используемый для построения формы.

  • :id — необязательный атрибут HTML id.

  • :class — необязательный атрибут HTML class.

  • :data — необязательные атрибуты данных HTML.

  • :html — другие необязательные атрибуты тега формы HTML.

Примеры

При отсутствии блока form_with генерируется только открывающий тег формы.

<%= form_with(model: @article, url: super_articles_path) %>
<%= form_with(model: @article, scope: :blog) %>
<%= form_with(model: @article, format: :json) %>
<%= form_with(model: @article, authenticity_token: false) %> # Disables the token.

Для маршрутов с именами пространств, например, admin_article_url:

<%= form_with(model: [ :admin, @article ]) do |form| %>
  ...
<% end %>

Если у вашего ресурса определены ассоциации, например, вы хотите добавить комментарии к документу при условии, что маршруты установлены правильно:

<%= form_with(model: [ @document, Comment.new ]) do |form| %>
  ...
<% end %>

Где @document = Document.find(params[:id]).

Смешение с другими помощниками форм

Хотя form_with использует объект FormBuilder, можно смешивать автономные методы FormHelper и методы из FormTagHelper:

<%= form_with scope: :person do |form| %>
  <%= form.text_field :first_name %>
  <%= form.text_field :last_name %>

  <%= textarea :person, :biography %>
  <%= checkbox_tag "person[admin]", "1", @person.company.admin? %>

  <%= form.submit %>
<% end %>

То же самое касается методов в FormOptionsHelper и DateHelper, предназначенных для работы с объектом в качестве базы, таких как FormOptionsHelper#collection_select и DateHelper#datetime_select.

Указание метода

Вы можете принудительно использовать полный набор HTTP-глаголов, установив

method: (:get|:post|:patch|:put|:delete)

в хеше параметров. Если глагол не GET или POST, которые встроены в HTML-формы, форма будет установлена на POST, и скрытое поле с именем _method будет содержать назначенный глагол, чтобы сервер его интерпретировал.

Установка атрибутов HTML

Вы можете установить атрибуты данных напрямую в хеше данных, но атрибуты HTML, кроме id и class, должны быть обернуты в ключ HTML:

<%= form_with(model: @article, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
  ...
<% end %>

генерирует

<form action="/articles/123" method="post" data-behavior="autosave" name="go">
  <input name="_method" type="hidden" value="patch" />
  ...
</form>

Удаление скрытых id моделей

Метод form_with автоматически включает id модели как скрытое поле в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите отключить скрытый id.

В следующем примере модель Article имеет много комментариев, хранящихся в ней в базе данных NoSQL, поэтому для комментариев нет первичного ключа.

<%= form_with(model: @article) do |form| %>
  <%= form.fields(:comments, skip_id: true) do |fields| %>
    ...
  <% end %>
<% end %>

Настраиваемые строители форм

Вы также можете создавать формы, используя настраиваемый класс FormBuilder. Наследуйте от FormBuilder и переопределите или определите ещё несколько помощников, затем используйте своего настраиваемого строителя. Например, предположим, что вы создали помощник, который автоматически добавляет метки к полям ввода формы.

<%= form_with model: @person, url: { action: "create" }, builder: LabellingFormBuilder do |form| %>
  <%= form.text_field :first_name %>
  <%= form.text_field :last_name %>
  <%= form.textarea :biography %>
  <%= form.checkbox :admin %>
  <%= form.submit %>
<% end %>

В этом случае, если вы используете:

<%= render form %>

Рендерируемый шаблон people/_labelling_form, а локальная переменная, ссылающаяся на строителя формы, называется labelling_form.

Настраиваемый класс FormBuilder автоматически объединяется с параметрами вложенного вызова fields, если он явно не установлен.

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

def labelled_form_with(**options, &block)
  form_with(**options.merge(builder: LabellingFormBuilder), &block)
end
hidden_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1215
def hidden_field(object_name, method, options = {})
  Tags::HiddenField.new(object_name, method, self, options).render
end

Возвращает тег скрытого поля, настроенный для доступа к указанному атрибуту (определённому по method) объекта, назначенного шаблону (определённого по object). Дополнительные параметры тега ввода могут быть переданы в виде хеша с options. Эти параметры будут добавлены в HTML как атрибуты элемента HTML, как показано в примере.

Примеры

hidden_field(:signup, :pass_confirm)
# => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />

hidden_field(:article, :tag_list)
# => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="#{@article.tag_list}" />

hidden_field(:user, :token)
# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
label(object_name, method, content_or_options = nil, options = nil, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1152
def label(object_name, method, content_or_options = nil, options = nil, &block)
  Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
end

Возвращает тег метки, настроенный для подписи поля ввода для указанного атрибута (определённого по method) объекта, назначенного шаблону (определённого по object). Текст метки по умолчанию будет соответствовать имени атрибута, если не найдено перевода в текущем языке I18n (через helpers.label.<modelname>.<attribute>) или вы явно его не укажете. Дополнительные параметры тега метки могут быть переданы в виде хеша с options. Эти параметры будут добавлены в HTML в виде атрибутов элемента HTML, как показано в примере, за исключением параметра :value, который предназначен для обработки меток для тегов radio_button (где значение используется в ID тега ввода).

Примеры

label(:article, :title)
# => <label for="article_title">Title</label>

Вы можете локализовать метки на основе имен модели и атрибутов. Например, вы можете определить следующее в своём локали (например, en.yml)

helpers:
  label:
    article:
      body: "Write your entire text here"

Что приведет к

label(:article, :body)
# => <label for="article_body">Write your entire text here</label>

Локализация также может основываться только на переводе имени атрибута (если вы используете ActiveRecord):

activerecord:
  attributes:
    article:
      cost: "Total cost"
label(:article, :cost)
# => <label for="article_cost">Total cost</label>

label(:article, :title, "A short title")
# => <label for="article_title">A short title</label>

label(:article, :title, "A short title", class: "title_label")
# => <label for="article_title" class="title_label">A short title</label>

label(:article, :privacy, "Public Article", value: "public")
# => <label for="article_privacy_public">Public Article</label>

label(:article, :cost) do |translation|
  content_tag(:span, translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>

label(:article, :cost) do |builder|
  content_tag(:span, builder.translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>

label(:article, :terms) do
  raw('Accept <a href="/terms">Terms</a>.')
end
# => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
month_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1534
def month_field(object_name, method, options = {})
  Tags::MonthField.new(object_name, method, self, options).render
end

Возвращает text_field типа «месяц».

month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="month" />

Значение по умолчанию генерируется путем попытки вызвать strftime с «%Y-%m» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.

@user.born_on = Date.new(1984, 1, 27)
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
number_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1578
def number_field(object_name, method, options = {})
  Tags::NumberField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа «число».

Параметры

Поддерживает те же параметры, что и FormTagHelper#number_field_tag.

password_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1197
def password_field(object_name, method, options = {})
  Tags::PasswordField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа «пароль», предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибут элемента HTML, как показано в примере. По соображениям безопасности это поле по умолчанию пустое; передайте значение через options , если этого не требуется.

Примеры

password_field(:login, :pass, size: 20)
# => <input type="password" id="login_pass" name="login[pass]" size="20" />

password_field(:account, :secret, class: "form_input", value: @account.secret)
# => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />

password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
# => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>

password_field(:account, :pin, size: 20, class: 'form_input')
# => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
phone_field(object_name, method, options = {})

алиас для telephone_field

Псевдоним для: telephone_field
radio_button(object_name, method, tag_value, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1370
def radio_button(object_name, method, tag_value, options = {})
  Tags::RadioButton.new(object_name, method, self, tag_value, options).render
end

Возвращает тег радиокнопки для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Если текущее значение method равно tag_value, радиокнопка будет отмечена.

Чтобы принудительно установить радиокнопку, передайте checked: true в хэш options. Вы также можете передать туда параметры HTML.

# Let's say that @article.category returns "rails":
radio_button("article", "category", "rails")
radio_button("article", "category", "java")
# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
#    <input type="radio" id="article_category_java" name="article[category]" value="java" />

# Let's say that @user.receive_newsletter returns "no":
radio_button("user", "receive_newsletter", "yes")
radio_button("user", "receive_newsletter", "no")
# => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
#    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
range_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1587
def range_field(object_name, method, options = {})
  Tags::RangeField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа «диапазон».

Параметры

Поддерживает те же параметры, что и FormTagHelper#range_field_tag.

rich_text_area(object_name, method, options = {})
Псевдоним для: rich_textarea
rich_textarea(object_name, method, options = {}) Показать исходный код
# File actiontext/app/helpers/action_text/tag_helper.rb, line 87
def rich_textarea(object_name, method, options = {})
  Tags::ActionText.new(object_name, method, self, options).render
end

Возвращает тег trix-editor, который инициализирует JavaScript-редактор Trix, а также скрытое поле, в которое Trix будет записывать изменения, чтобы содержимое отправлялось при отправке формы.

Параметры

  • :class - По умолчанию «trix-content», что обеспечивает применение стилей по умолчанию.

  • :value - Добавляет значение по умолчанию в тег ввода HTML.

  • [:data][:direct_upload_url] - По умолчанию rails_direct_uploads_url.

  • [:data][:blob_url_template] - По умолчанию rails_service_blob_url(":signed_id", ":filename").

Пример

rich_textarea :message, :content
# <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
# <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>

rich_textarea :message, :content, value: "<h1>Default message</h1>"
# <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
# <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
Также алиас для: rich_text_area
search_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1401
def search_field(object_name, method, options = {})
  Tags::SearchField.new(object_name, method, self, options).render
end

Возвращает поле ввода типа «поиск» для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object_name). Поля ввода типа «поиск» могут отображаться браузерами по-разному.

search_field(:user, :name)
# => <input id="user_name" name="user[name]" type="search" />
search_field(:user, :name, autosave: false)
# => <input autosave="false" id="user_name" name="user[name]" type="search" />
search_field(:user, :name, results: 3)
# => <input id="user_name" name="user[name]" results="3" type="search" />
#  Assume request.host returns "www.example.com"
search_field(:user, :name, autosave: true)
# => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" />
search_field(:user, :name, onsearch: true)
# => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
search_field(:user, :name, autosave: false, onsearch: true)
# => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
search_field(:user, :name, autosave: true, onsearch: true)
# => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
telephone_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1410
def telephone_field(object_name, method, options = {})
  Tags::TelField.new(object_name, method, self, options).render
end

Возвращает text_field типа «тел».

telephone_field("user", "phone")
# => <input id="user_phone" name="user[phone]" type="tel" />
Также алиас для: phone_field
text_area(object_name, method, options = {})
Псевдоним для: textarea
text_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1176
def text_field(object_name, method, options = {})
  Tags::TextField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа «текст», предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибут элемента HTML, как показано в примере.

Примеры

text_field(:article, :title, size: 20)
# => <input type="text" id="article_title" name="article[title]" size="20" value="#{@article.title}" />

text_field(:article, :title, class: "create_input")
# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" class="create_input" />

text_field(:article, :title,  maxlength: 30, class: "title_input")
# => <input type="text" id="article_title" name="article[title]" maxlength="30" size="30" value="#{@article.title}" class="title_input" />

text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
# => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>

text_field(:snippet, :code, size: 20, class: 'code_input')
# => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
textarea(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1278
def textarea(object_name, method, options = {})
  Tags::TextArea.new(object_name, method, self, options).render
end

Возвращает набор открывающего и закрывающего тегов textarea, предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options.

Примеры

textarea(:article, :body, cols: 20, rows: 40)
# => <textarea cols="20" rows="40" id="article_body" name="article[body]">
#      #{@article.body}
#    </textarea>

textarea(:comment, :text, size: "20x30")
# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
#      #{@comment.text}
#    </textarea>

textarea(:application, :notes, cols: 40, rows: 15, class: 'app_input')
# => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input">
#      #{@application.notes}
#    </textarea>

textarea(:entry, :body, size: "20x20", disabled: 'disabled')
# => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
#      #{@entry.body}
#    </textarea>
Также алиас для: text_area
time_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1480
def time_field(object_name, method, options = {})
  Tags::TimeField.new(object_name, method, self, options).render
end

Возвращает text_field типа «время».

Значение по умолчанию генерируется путем попытки вызвать strftime с «%T.%L» на значении объекта. Если вы передаете include_seconds: false, оно будет отформатировано путем попытки вызвать strftime с «%H:%M» на значении объекта. Также можно переопределить это, передав параметр «value».

Параметры

Поддерживает те же параметры, что и FormTagHelper#time_field_tag.

Примеры

time_field("task", "started_at")
# => <input id="task_started_at" name="task[started_at]" type="time" />

Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.

time_field("task", "started_at", min: Time.now)
# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />

В качестве значений для «min» и «max» также можно передать строку, отформатированную как ISO8601 время.

time_field("task", "started_at", min: "01:00:00")
# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />

По умолчанию, указанное время будет отформатировано, включая секунды. Для отображения только часа и минуты передайте include_seconds: false. Некоторые браузеры отобразят более простой интерфейс, если вы исключите секунды в формате метки времени.

time_field("task", "started_at", value: Time.now, include_seconds: false)
# => <input id="task_started_at" name="task[started_at]" type="time" value="01:00" />
url_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1560
def url_field(object_name, method, options = {})
  Tags::UrlField.new(object_name, method, self, options).render
end

Возвращает text_field типа “url”.

url_field("user", "homepage")
# => <input id="user_homepage" name="user[homepage]" type="url" />
week_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1551
def week_field(object_name, method, options = {})
  Tags::WeekField.new(object_name, method, self, options).render
end

Возвращает text_field типа “week”.

week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="week" />

Значение по умолчанию генерируется путем вызова strftime с “%Y-W%W” на значении объекта, что делает его поведением, ожидаемым для экземпляров DateTime и ActiveSupport::TimeWithZone.

@user.born_on = Date.new(1984, 5, 12)
week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-W19" />

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

Spec-Zone.ru

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