Spec-Zone.ru › Ruby on Rails 7.2

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

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

Помощники для форм Action View

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

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

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

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

<%= form_for @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 является существующей записью с именем «John Smith» и 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") Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1345
def check_box(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 гласит, что неотмеченные checkboxes не обрабатываются корректно, и поэтому веб-браузеры их не отправляют. К сожалению, это приводит к проблеме: если у модели Invoice есть флаг paid, а в форме редактирования платёжного счета пользователь сбрасывает флажок, параметр paid не отправляется. Таким образом, любой idiom массового назначения, например:

@invoice.update(params[:invoice])

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

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

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

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

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

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

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

Примеры

# Let's say that @article.validated? is 1:
check_box("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":
check_box("puppy", "gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
#    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />

check_box("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" />
color_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1375
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 1439
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 1512
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 1566
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 1079
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

Ограничивает поля ввода либо явным scope, либо моделью. Похоже на то, как 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, связанный с scope или моделью, таким образом, все сгенерированные имена полей предваряются либо переданным scope, либо scope, выведенным из :model.

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

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

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

  <%= text_area :commenter, :biography %>
  <%= check_box_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 1028
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, он передаёт объект 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.check_box :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.check_box :admin %>
<% end %>

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

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

<%= fields_for @person.permission do |permission_fields| %>
  Admin?: <%= permission_fields.check_box :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.check_box :_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 как коллекцию и правильно установил индексы в разметке формы.

Если проекты уже являются ассоциацией в 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.check_box :_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 1247
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 435
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.text_area :biography %><br />
  Admin?    : <%= f.check_box :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 добавляется для имитации глагола над отправкой.

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

  • :remote - Если установлено в значение true, это позволит драйверам Unobtrusive 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 : <%= text_area :person, :biography %>
  Admin?    : <%= check_box_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>

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

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

В следующем примере модель Article имеет несколько Comments, хранящихся внутри неё в базе данных 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.text_area :biography %>
  <%= f.check_box :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 755
def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block)
  ActionView.deprecator.warn("Passing nil to the :model argument is deprecated and will raise in Rails 8.0") 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 %>

  <%= text_area :person, :biography %>
  <%= check_box_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 не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите отключить скрытый идентификатор.

В следующем примере модель 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.text_area :biography %>
  <%= form.check_box :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 1214
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 1151
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 (где значение используется в идентификаторе тега ввода).

Примеры

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 1531
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 1575
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 1196
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 1367
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 1584
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 = {}) Показать исходный код
# File actiontext/app/helpers/action_text/tag_helper.rb, line 86
def rich_text_area(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_text_area :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_text_area :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>
search_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1398
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 1407
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 = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1277
def text_area(object_name, method, options = {})
  Tags::TextArea.new(object_name, method, self, options).render
end

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

Примеры

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

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

text_area(: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>

text_area(:entry, :body, size: "20x20", disabled: 'disabled')
# => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
#      #{@entry.body}
#    </textarea>
text_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1175
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" />
time_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1477
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" />

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

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 1557
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 1548
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