Spec-Zone.ru › Ruby on Rails 6.0

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

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

Помощники для форм предназначены для упрощения работы с ресурсами по сравнению с использованием обычного 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 1300
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 отмечен. Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Значение по умолчанию для checked_value равно 1, а значение по умолчанию для unchecked_value равно 0, что удобно для булевых значений.

Примечание

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

@invoice.update(params[:invoice])

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

Для предотвращения этого помощник генерирует дополнительное скрытое поле перед чекбоксом. Скрытое поле имеет то же имя, а его атрибуты имитируют неотмеченный 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 1330
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 1394
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" />

В качестве альтернативы, вы можете передать строку, отформатированную как дата 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 1452
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" />

В качестве альтернативы, вы можете передать строку, отформатированную как 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" />
Также алиас: 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 1506
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 1057
def fields(scope = nil, model: nil, **options, &block)
  options[:allow_method_names_outside_object] = true
  options[:skip_default_ids] = !form_with_generates_ids

  if 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, связанный с областью действия или моделью, передается в блок, поэтому все сгенерированные имена полей имеют префикс либо с указанной областью действия, либо с областью действия, определенной по :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, предназначенным для работы с объектом в качестве основы, как ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::DateHelper#datetime_select.

fields_for(record_name, record_object = nil, options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1007
def fields_for(record_name, record_object = nil, options = {}, &block)
  builder = instantiate_builder(record_name, record_object, options)
  capture(builder, &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 %>

В этом случае поле флажка будет представлено тегом 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, которые предназначены для работы с объектом в качестве основы, например, ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::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_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 %>

Если address уже является ассоциацией в 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 автоматически сгенерирует скрытое поле для хранения идентификатора записи. В некоторых случаях это скрытое поле не требуется, и вы можете передать include_id: false , чтобы предотвратить автоматическое рендеринг #fields_for.

file_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1212
def file_field(object_name, method, 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, *в большинстве современных браузеров* пользователь сможет выбрать несколько файлов.

  • :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 430
def form_for(record, options = {}, &block)
  raise ArgumentError, "Missing block" unless block_given?
  html_options = options[:html] ||= {}

  case record
  when String, Symbol
    object_name = record
    object      = nil
  else
    object      = record.is_a?(Array) ? record.last : 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!(record, object, options)
  end

  html_options[:data]   = options.delete(:data)   if options.has_key?(:data)
  html_options[:remote] = options.delete(:remote) if options.has_key?(:remote)
  html_options[:method] = options.delete(:method) if options.has_key?(:method)
  html_options[:enforce_utf8] = options.delete(:enforce_utf8) if options.has_key?(:enforce_utf8)
  html_options[:authenticity_token] = options.delete(:authenticity_token)

  builder = instantiate_builder(object_name, object, options)
  output  = capture(builder, &block)
  html_options[:multipart] ||= builder.multipart?

  html_options = html_options_for_form(options[:url] || {}, html_options)
  form_tag_with_body(html_options, output)
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 добавляется для имитации глагола через post.

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

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

  • :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, которые предназначены для работы с объектом в качестве основы, например, ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::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 %>

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

<%= 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 изменять её поведение. Ожидаемое поведение по умолчанию — это отправка XMLHttpRequest в фоновом режиме вместо обычной POST-отправки, но в конечном итоге поведение зависит от реализатора драйвера JavaScript. Несмотря на то, что для сериализации элементов формы используется 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>

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

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

В следующем примере модель Post имеет множество Comments, хранящихся в ней в базе данных 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

Если вам не нужно привязывать форму к экземпляру модели, см. ActionView::Helpers::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: nil, scope: nil, url: nil, format: nil, **options, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 742
def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block)
  options[:allow_method_names_outside_object] = true
  options[:skip_default_ids] = !form_with_generates_ids

  if model
    url ||= polymorphic_path(model, format: format)

    model   = model.last if model.is_a?(Array)
    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" data-remote="true">
  <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" data-remote="true">
  <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" data-remote="true">
  <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" data-remote="true">
  <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" data-remote="true">
  <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] соответственно.

По умолчанию form_with добавляет атрибут data-remote, отправляя форму через XMLHTTPRequest в фоновом режиме, если используется драйвер Unobtrusive JavaScript, такой как rails-ujs. Более подробно см. опцию :local.

Для простоты сравнения в примерах выше отсутствуют кнопки отправки, а также автоматически сгенерированные скрытые поля, которые обеспечивают поддержку 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, чтобы имитировать глагол через post.

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

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

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

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

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

  • :local - По умолчанию отправка форм является дистанционной и ненавязчивой XHR. Отключить дистанционные отправки с помощью local: true.

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

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

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

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

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

  • :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, предназначенным для работы с объектом в качестве основы, например ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::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>

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

Метод 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 %>

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

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 1180
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 1117
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, :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 1471
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1514
def number_field(object_name, method, options = {})
  Tags::NumberField.new(object_name, method, self, options).render
end

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

Параметры

  • Принимает те же параметры, что и number_field_tag

password_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1162
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1322
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1522
def range_field(object_name, method, options = {})
  Tags::RangeField.new(object_name, method, self, options).render
end

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

Параметры

  • Принимает те же параметры, что и range_field_tag

rich_text_area(object_name, method, options = {}) Show source
# File actiontext/app/helpers/action_text/tag_helper.rb, line 69
def rich_text_area(object_name, method, options = {})
  Tags::ActionText.new(object_name, method, self, options).render
end

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

Параметры

  • :class — по умолчанию “trix-content”, что гарантирует применение стилей по умолчанию.

Пример

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>
search_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1353
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1362
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1240
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1141
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1423
def time_field(object_name, method, options = {})
  Tags::TimeField.new(object_name, method, self, options).render
end

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

Значение по умолчанию генерируется путём вызова strftime с “%T.%L” на значении объекта. Возможно переопределение этого параметра с помощью опции “value”.

Параметры

  • Принимает те же параметры, что и 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" />
url_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1497
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1488
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–2019 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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