Spec-Zone.ru › Ruby on Rails 7.1

модуль 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 1341
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 @post.validated? is 1:
check_box("post", "validated")
# => <input name="post[validated]" type="hidden" value="0" />
#    <input checked="checked" type="checkbox" id="post_validated" name="post[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 1371
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 1435
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 1508
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 1562
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 1077
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: @post 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 1026
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_for, но не создаёт сами теги формы. Это делает fields_for подходящим для указания дополнительных объектов модели в той же форме.

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

<%= form_for @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 %>

В этом случае поле checkbox будет представлено 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_attributes=:

class Person
  def address
    @address
  end

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

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

<%= form_for @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_for @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 как коллекцию и установил правильные индексы в разметке формы.

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

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

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

<%= form_for @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_for @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_for @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_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    Delete: <%= project_fields.check_box :_destroy %>
  <% end %>
  ...
<% end %>

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

<%= form_for @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 1243
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_for установит кодировку окружающей формы на 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(:post, :image, multiple: true)
# => <input type="file" id="post_image" name="post[image][]" multiple="multiple" />

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

file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg')
# => <input type="file" id="post_image" name="post[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 434
def form_for(record, options = {}, &block)
  raise ArgumentError, "Missing block" unless block_given?

  case record
  when String, Symbol
    model       = nil
    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 — пространство имён для вашей формы, чтобы обеспечить уникальность идентификаторов элементов формы. Атрибут пространства имён будет префиксным с символом подчёркивания к сгенерированному HTML-идентификатору.

  • :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. Например, если @post — это существующая запись, которую вы хотите отредактировать, вы можете создать форму, используя

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

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

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

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

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

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

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

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

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

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

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

<%= form_for @post, as: :post, url: post_path(@post), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>
  ...
<% end %>

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

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

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

<%= form_for @post, as: :post, url: posts_path, html: { class: "new_post", id: "new_post" } do |f| %>
  ...
<% end %>

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

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

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

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

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

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

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

<%= form_for([:admin, @post]) 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(@post, 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(@post, 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 автоматически включает идентификатор модели в виде скрытого поля в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые ORM-системы не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите иметь возможность отключить скрытый идентификатор.

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

Пример:

<%= form_for(@post) 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 %>
END_OF_DOCUMENT_MARKER
form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 755
def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block)
  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: posts_path do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/posts" 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: :post, url: posts_path do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/posts" method="post">
  <input type="text" name="post[title]">
</form>

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

# An existing model makes an update form and fills out field values:
<%= form_with model: Post.first do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/posts/1" method="post">
  <input type="hidden" name="_method" value="patch">
  <input type="text" name="post[title]" value="<the title of the post>">
</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 и post[title] доступны как params[:title] и params[:post][:title] соответственно.

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

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

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

Таким образом, при передаче такой записи модели Rails определяет URL-адрес и метод.

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

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

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

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

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

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

<%= form_with scope: :post, url: posts_path do |form| %>
  ...
<% end %>

Опции

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

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

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

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

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

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

  • :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 data.

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

Примеры

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

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

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

<%= form_with(model: [ :admin, @post ]) 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: @post, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
  ...
<% end %>

генерирует

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

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

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

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

<%= form_with(model: @post) 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 1210
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(:post, :tag_list)
# => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.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 1147
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(:post, :title)
# => <label for="post_title">Title</label>

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

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

Что затем приведёт к

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

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

activerecord:
  attributes:
    post:
      cost: "Total cost"

label(:post, :cost)
# => <label for="post_cost">Total cost</label>

label(:post, :title, "A short title")
# => <label for="post_title">A short title</label>

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

label(:post, :privacy, "Public Post", value: "public")
# => <label for="post_privacy_public">Public Post</label>

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

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

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

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

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 1571
def number_field(object_name, method, options = {})
  Tags::NumberField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа “number”.

Параметры

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

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

Возвращает тег ввода типа “password”, предназначенный для доступа к указанному атрибуту (определяемому 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 1363
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 @post.category returns "rails":
radio_button("post", "category", "rails")
radio_button("post", "category", "java")
# => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
#    <input type="radio" id="post_category_java" name="post[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 1580
def range_field(object_name, method, options = {})
  Tags::RangeField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа “range”.

Параметры

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

rich_text_area(object_name, method, options = {}) Показать исходный код
# File actiontext/app/helpers/action_text/tag_helper.rb, line 80
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").

Пример

form_with(model: @message) do |form|
  form.rich_text_area :content
end
# <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>

form_with(model: @message) do |form|
  form.rich_text_area :content, value: "<h1>Default message</h1>"
end
# <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 1394
def search_field(object_name, method, options = {})
  Tags::SearchField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа “search” для доступа к указанному атрибуту (определяемому method) объекта, присвоенного шаблону (определяемому object_name). В некоторых браузерах теги типа “search” могут иметь разную стилизацию.

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 1403
def telephone_field(object_name, method, options = {})
  Tags::TelField.new(object_name, method, self, options).render
end

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

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 1273
def text_area(object_name, method, options = {})
  Tags::TextArea.new(object_name, method, self, options).render
end

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

Примеры

text_area(:post, :body, cols: 20, rows: 40)
# => <textarea cols="20" rows="40" id="post_body" name="post[body]">
#      #{@post.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 1171
def text_field(object_name, method, options = {})
  Tags::TextField.new(object_name, method, self, options).render
end

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

Примеры

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

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

text_field(:post, :title,  maxlength: 30, class: "title_input")
# => <input type="text" id="post_title" name="post[title]" maxlength="30" size="30" value="#{@post.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 1473
def time_field(object_name, method, options = {})
  Tags::TimeField.new(object_name, method, self, options).render
end

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

Значение по умолчанию генерируется путем вызова 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.

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 1553
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 1544
def week_field(object_name, method, options = {})
  Tags::WeekField.new(object_name, method, self, options).render
end

Возвращает text_field типа “неделя”.

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