Spec-Zone.ru › Ruby on Rails 7.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 — это существующий ресурс с именем «Иван Иванов» и 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 1335
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

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

Параметры

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

  • :checked - true или false принудительно устанавливает или снимает флажок.

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

Примечание

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

@invoice.update(params[:invoice])

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

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

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

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

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

потому что повторение имен параметров — это именно то, что Rails стремится различать элементы массива. Для каждого элемента с установленным флажком вы получаете дополнительный «фантомный» элемент только с этим атрибутом, присвоенным «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 1365
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 1429
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 1494
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" />
Также известен как: 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 1548
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 1071
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 1020
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, он передаёт объект 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, начальное состояние checkbox при первом отображении будет отражать значение @person.permission.admin.

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

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

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

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

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

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

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

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

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

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

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

Один-к-одному

Рассмотрим класс Person, который возвращает один объект Address из метода-члена address и реагирует на метод-сеттер address_attributes=:

class Person
  def address
    @address
  end

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

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

<%= form_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 как коллекцию, и для корректного задания индексов в разметке формы.

Если проекты уже являются ассоциацией в 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 %>

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

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

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

file_field(object_name, method, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 1237
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(method, options)).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 433
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 — пространство имён для вашей формы, чтобы гарантировать уникальность атрибутов id элементов формы. Атрибут пространства имён будет предваряться подчёркиванием в сгенерированном HTML id.

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

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

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

  • :enforce_utf8 — если установлено в false, скрытый input с именем 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, а скрытый input с именем _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 автоматически включает id модели в виде скрытого поля в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют ID для вложенных моделей, поэтому в этом случае вам нужно иметь возможность отключить скрытый id.

В следующем примере модель 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 %>
form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_helper.rb, line 754
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 ||= polymorphic_path(model, format: format)
    end

    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" 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">
  <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 %>

Параметры form_with

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

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

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

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

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

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

Вы можете установить атрибуты data напрямую в хеше data, но атрибуты 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 автоматически включает id модели в виде скрытого поля в форме. Это используется для поддержания корреляции между данными формы и её связанной моделью. Некоторые ORM-системы не используют ID для вложенных моделей, поэтому в этом случае вы хотите иметь возможность отключить скрытый ID.

В следующем примере модель 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 1204
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 1141
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 (через помощники 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 1513
def month_field(object_name, method, options = {})
  Tags::MonthField.new(object_name, method, self, options).render
end

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

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

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

@user.born_on = Date.new(1984, 1, 27)
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
number_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1556
def number_field(object_name, method, options = {})
  Tags::NumberField.new(object_name, method, self, options).render
end

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

Параметры

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

password_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1186
def password_field(object_name, method, options = {})
  Tags::PasswordField.new(object_name, method, self, options).render
end

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

Примеры

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

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

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

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

псевдоним telephone_field

Псевдоним для: telephone_field
radio_button(object_name, method, tag_value, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1357
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 1564
def range_field(object_name, method, options = {})
  Tags::RangeField.new(object_name, method, self, options).render
end

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

Параметры

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

rich_text_area(object_name, method, options = {}) Show source
# File actiontext/app/helpers/action_text/tag_helper.rb, line 87
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 = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1388
def search_field(object_name, method, options = {})
  Tags::SearchField.new(object_name, method, self, options).render
end

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

search_field(:user, :name)
# => <input id="user_name" name="user[name]" type="search" />
search_field(:user, :name, autosave: false)
# => <input autosave="false" id="user_name" name="user[name]" type="search" />
search_field(:user, :name, results: 3)
# => <input id="user_name" name="user[name]" results="3" type="search" />
#  Assume request.host returns "www.example.com"
search_field(:user, :name, autosave: true)
# => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" />
search_field(:user, :name, onsearch: true)
# => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
search_field(:user, :name, autosave: false, onsearch: true)
# => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
search_field(:user, :name, autosave: true, onsearch: true)
# => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
telephone_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1397
def telephone_field(object_name, method, options = {})
  Tags::TelField.new(object_name, method, self, options).render
end

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

telephone_field("user", "phone")
# => <input id="user_phone" name="user[phone]" type="tel" />
Также алиас: phone_field
text_area(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1267
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 1165
def text_field(object_name, method, options = {})
  Tags::TextField.new(object_name, method, self, options).render
end

Возвращает тег ввода типа “текст”, настроенный для доступа к указанному атрибуту (определяемому как 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 1465
def time_field(object_name, method, options = {})
  Tags::TimeField.new(object_name, method, self, options).render
end

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

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

Параметры

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

Пример

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

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

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

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

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

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

time_field("task", "started_at", value: Time.now, include_seconds: false)
# => <input id="task_started_at" name="task[started_at]" type="time" value="01:00" />
url_field(object_name, method, options = {}) Show source
# File actionview/lib/action_view/helpers/form_helper.rb, line 1539
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 1530
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