модуль ActionView::Helpers::FormHelper
Помощники для форм Action View
Помощники для форм разработаны, чтобы работа с ресурсами была намного проще по сравнению с использованием обычного HTML.
Обычно форма, предназначенная для создания или обновления ресурса, отражает идентичность ресурса несколькими способами: (i) URL, к которому отправляется форма (атрибут элемента формы action) должен привести к перенаправлению запроса на соответствующее действие контроллера (с соответствующим параметром :id в случае существующего ресурса), (ii) поля ввода должны быть именованы таким образом, чтобы в контроллере их значения появлялись в соответствующих местах внутри хеша params, и (iii) для существующего записей, когда форма первоначально отображается, поля ввода, соответствующие атрибутам ресурса, должны отображать текущие значения этих атрибутов.
В Rails это обычно достигается путем создания формы с использованием form_for и ряда связанных методов-помощников. form_for генерирует соответствующий тег form и передает объект генератора форм, который знает модель, к которой относится форма. Поля ввода создаются путем вызова методов, определенных в генераторе форм, что означает, что они могут генерировать соответствующие имена и значения по умолчанию, соответствующие атрибутам модели, а также удобные идентификаторы и т. д. Конвенции в сгенерированных именах полей позволяют контроллерам получать данные формы, красиво структурированные в params без каких-либо усилий с вашей стороны.
Например, для создания новой записи человека вы обычно создаёте новый экземпляр Person в действии PeopleController#new, @person, и в шаблоне представления передаёте этот объект в form_for:
<%= form_for @person do |f| %> <%= f.label :first_name %>: <%= f.text_field :first_name %><br /> <%= f.label :last_name %>: <%= f.text_field :last_name %><br /> <%= f.submit %> <% end %>
Сгенерированный HTML для этого будет (модуль форматирования):
<form action="/people" class="new_person" id="new_person" method="post"> <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> <label for="person_first_name">First name</label>: <input id="person_first_name" name="person[first_name]" type="text" /><br /> <label for="person_last_name">Last name</label>: <input id="person_last_name" name="person[last_name]" type="text" /><br /> <input name="commit" type="submit" value="Create Person" /> </form>
Как видите, HTML отражает знания о ресурсе в нескольких местах, таких как путь, по которому должна быть отправлена форма, или имена полей ввода.
В частности, благодаря соглашениям, используемым в именах сгенерированных полей, контроллер получает вложенный хеш params[:person] с атрибутами человека, установленными в форме. Этот хеш готов для передачи в Person.new:
@person = Person.new(params[:person]) if @person.save # success else # error handling end
Интересно, что тот же самый код представления в предыдущем примере может использоваться для редактирования человека. Если @person является существующей записью с именем «John Smith» и ID 256, код выше таким, как есть, будет возвращать:
<form action="/people/256" class="edit_person" id="edit_person_256" method="post"> <input name="_method" type="hidden" value="patch" /> <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> <label for="person_first_name">First name</label>: <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br /> <label for="person_last_name">Last name</label>: <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br /> <input name="commit" type="submit" value="Update Person" /> </form>
Обратите внимание, что конечная точка, значения по умолчанию и подпись кнопки отправки настроены для @person. Это работает таким образом, потому что связанные помощники знают, является ли ресурс новой записью или нет, и генерируют HTML соответствующим образом.
Контроллер снова получит данные формы в params[:person], готовые для передачи в Person#update:
if @person.update(params[:person]) # success else # error handling end
Вот как вы обычно работаете с ресурсами.
Публичные методы экземпляра
# File actionview/lib/action_view/helpers/form_helper.rb, line 1345
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render
end Возвращает тег checkbox, настроенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, назначенного шаблону (идентифицируемому по object). Этот объект должен быть объектом экземпляра (@object), а не локальным объектом. Предполагается, что method возвращает целое число, и если это целое число больше нуля, то checkbox помечен. Дополнительные параметры тега input могут быть переданы в виде хэша с options. Значение checked_value по умолчанию равно 1, а значение по умолчанию unchecked_value установлено в 0, что удобно для логических значений.
Параметры
-
Любые стандартные атрибуты HTML для тега могут быть переданы, например
:class. -
:checked-trueилиfalseпринудительно устанавливают состояние checkbox в отмеченное или не отмеченное состояние. -
:include_hidden- Если установлено в false, вспомогательное скрытое поле, описанное ниже, не будет сгенерировано.
Особенности
Спецификация HTML гласит, что неотмеченные checkboxes не обрабатываются корректно, и поэтому веб-браузеры их не отправляют. К сожалению, это приводит к проблеме: если у модели Invoice есть флаг paid, а в форме редактирования платёжного счета пользователь сбрасывает флажок, параметр paid не отправляется. Таким образом, любой idiom массового назначения, например:
@invoice.update(params[:invoice])
не обновил бы флаг.
Чтобы предотвратить это, помощник генерирует вспомогательное скрытое поле перед каждым checkbox. У скрытого поля то же имя, а его атрибуты имитируют неотмеченный checkbox.
Таким образом, клиент отправляет только скрытое поле (что соответствует неотмеченному checkbox) или оба поля. Так как спецификация HTML говорит, что пары ключ/значение должны отправляться в том же порядке, в котором они появляются в форме, а извлечение параметров получает последнее вхождение любого повторяющегося ключа в строке запроса, это работает для обычных форм.
К сожалению, это решение не работает, когда checkbox находится внутри массивоподобного параметра, как в
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> <%= form.check_box :paid %> ... <% end %>
потому что повторение имён параметров — именно то, что Rails стремится различать элементы массива. Для каждого элемента с отмеченным checkbox вы получаете дополнительный «призрачный» элемент только с этим атрибутом, присвоенным «0».
В этом случае предпочтительнее использовать check_box_tag или использовать хэши вместо массивов.
Примеры
# Let's say that @article.validated? is 1:
check_box("article", "validated")
# => <input name="article[validated]" type="hidden" value="0" />
# <input checked="checked" type="checkbox" id="article_validated" name="article[validated]" value="1" />
# Let's say that @puppy.gooddog is "no":
check_box("puppy", "gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
# <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no")
# => <input name="eula[accepted]" type="hidden" value="no" />
# <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1375
def color_field(object_name, method, options = {})
Tags::ColorField.new(object_name, method, self, options).render
end Возвращает text_field типа «color».
color_field("car", "color")
# => <input id="car_color" name="car[color]" type="color" value="#000000" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1439
def date_field(object_name, method, options = {})
Tags::DateField.new(object_name, method, self, options).render
end Возвращает text_field типа «date».
date_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" />
Значение по умолчанию генерируется путём попытки вызвать strftime с «%Y-%m-%d» для значения объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone. Вы всё ещё можете переопределить это, явно передав параметр «value», например:
@user.born_on = Date.new(1984, 1, 27)
date_field("user", "born_on", value: "1984-05-12")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />
Вы можете создать значения для атрибутов «min» и «max», передавая экземпляры Date или Time в хэш параметров.
date_field("user", "born_on", min: Date.today)
# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
В качестве альтернативы вы можете передать String, отформатированный как дата ISO8601, в качестве значений для «min» и «max».
date_field("user", "born_on", min: "2014-05-20")
# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1512
def datetime_field(object_name, method, options = {})
Tags::DatetimeLocalField.new(object_name, method, self, options).render
end Возвращает text_field типа «datetime-local».
datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
Значение по умолчанию генерируется путём попытки вызвать strftime с «%Y-%m-%dT%T» для значения объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.
@user.born_on = Date.new(1984, 1, 12)
datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
Вы можете создать значения для атрибутов «min» и «max», передавая экземпляры Date или Time в хэш параметров.
datetime_field("user", "born_on", min: Date.today)
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
В качестве альтернативы вы можете передать String, отформатированный как дата-время ISO8601, в качестве значений для «min» и «max».
datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
По умолчанию, заданные значения даты и времени будут отформатированы, включая секунды. Можно отобразить только дату, час и минуту, передав include_seconds: false.
@user.born_on = Time.current
datetime_field("user", "born_on", include_seconds: false)
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1566
def email_field(object_name, method, options = {})
Tags::EmailField.new(object_name, method, self, options).render
end Возвращает text_field типа «email».
email_field("user", "address")
# => <input id="user_address" name="user[address]" type="email" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1079
def fields(scope = nil, model: nil, **options, &block)
options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
if model
model = _object_for_form_builder(model)
scope ||= model_name_from_record_or_class(model).param_key
end
builder = instantiate_builder(scope, model, options)
capture(builder, &block)
end Ограничивает поля ввода либо явным scope, либо моделью. Похоже на то, как form_with работает с :scope или :model, за исключением того, что не выводит теги формы.
# Using a scope prefixes the input field names:
<%= fields :comment do |fields| %>
<%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]">
# Using a model infers the scope and assigns field values:
<%= fields model: Comment.new(body: "full bodied") do |fields| %>
<%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]" value="full bodied">
# Using +fields+ with +form_with+:
<%= form_with model: @article do |form| %>
<%= form.text_field :title %>
<%= form.fields :comment do |fields| %>
<%= fields.text_field :body %>
<% end %>
<% end %> Подобно form_with, передаётся экземпляр FormBuilder, связанный с scope или моделью, таким образом, все сгенерированные имена полей предваряются либо переданным scope, либо scope, выведенным из :model.
Смешивание с другими помощниками форм
Хотя form_with использует объект FormBuilder, можно смешивать и сопоставлять автономные методы FormHelper и методы из FormTagHelper:
<%= fields model: @comment do |fields| %> <%= fields.text_field :body %> <%= text_area :commenter, :biography %> <%= check_box_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %> <% end %>
То же самое относится к методам в FormOptionsHelper и DateHelper, предназначенным для работы с объектом в качестве основы, таких как FormOptionsHelper#collection_select и DateHelper#datetime_select.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1028
def fields_for(record_name, record_object = nil, options = {}, &block)
options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options)
fields(record_name, **options, &block)
end Создаёт область вокруг определённого объекта модели, например, form_with, но не создаёт сами теги формы. Это делает fields_for подходящим для указания дополнительных объектов модели в одной форме.
Несмотря на сходство в использовании и назначении с fields_for, его сигнатура метода немного отличается. Как и form_with, он передаёт объект FormBuilder, связанный с конкретным объектом модели, в блок, и внутри блока можно вызывать методы для генерации полей, связанных с объектом модели. Поля могут отражать объект модели двумя способами — как они названы (а значит, как значения отправляются в params хэш-значение в контроллере) и какие значения по умолчанию отображаются при первом отображении полей формы. Для того, чтобы оба эти аспекта можно было указать независимо, можно передавать как имя объекта (представленное символом или строкой), так и сам объект методу отдельно —
<%= form_with model: @person do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for :permission, @person.permission do |permission_fields| %>
Admin? : <%= permission_fields.check_box :admin %>
<% end %>
<%= person_form.submit %>
<% end %> В этом случае поле флажка будет представлено тегом HTML input с атрибутом name значением permission[admin], а переданное значение появится в контроллере как params[:permission][:admin]. Если @person.permission — это существующий объект с атрибутом admin, начальное состояние флажка при первом отображении будет отражать значение @person.permission.admin.
Часто это можно упростить, передавая только имя объекта модели в fields_for —
<%= fields_for :permission do |permission_fields| %> Admin?: <%= permission_fields.check_box :admin %> <% end %>
…в этом случае, если :permission также является именем переменной экземпляра @permission, начальное состояние поля ввода будет отражать значение атрибута этой переменной @permission.admin.
В качестве альтернативы можно передать только сам объект модели (если первый аргумент не является строкой или символом fields_for поймёт, что имя опущено) —
<%= fields_for @person.permission do |permission_fields| %> Admin?: <%= permission_fields.check_box :admin %> <% end %>
и fields_for определит необходимое имя поля по классу объекта модели, например, если @person.permission, является экземпляром класса Permission, поле по-прежнему будет именоваться permission[admin].
Примечание: Это также работает для методов в FormOptionsHelper и DateHelper, которые предназначены для работы с объектом в качестве основы, например, FormOptionsHelper#collection_select и DateHelper#datetime_select.
Примеры вложенных атрибутов
Когда объект, принадлежащий текущей области видимости, имеет метод записи вложенного атрибута для определённого атрибута, fields_for создаст новую область видимости для этого атрибута. Это позволяет создавать формы, которые одновременно устанавливают или изменяют атрибуты родительского объекта и его ассоциаций.
Методы записи вложенных атрибутов являются обычными методами установки, имеющими имена, соответствующие ассоциации. Наиболее распространённый способ определения этих методов — с помощью accepts_nested_attributes_for в определении модели или путём определения метода с соответствующим именем. Например, метод записи атрибута для ассоциации :address называется address_attributes=.
Тип формы-генератора для одного к одному или одного ко многим будет зависеть от того, возвращает ли обычный метод чтения один объект или массив объектов.
Один к одному
Рассмотрим класс Person, который возвращает один объект Address из метода чтения address и реагирует на метод записи address_attributes=:
class Person
def address
@address
end
def address_attributes=(attributes)
# Process the attributes hash
end
end
Теперь эту модель можно использовать с вложенным fields_for, как показано ниже:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
Street : <%= address_fields.text_field :street %>
Zip code: <%= address_fields.text_field :zip_code %>
<% end %>
...
<% end %> Если адрес уже является ассоциацией в Person, вы можете использовать accepts_nested_attributes_for для определения метода записи за вас:
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address end
Если вы хотите удалить связанную модель через форму, сначала необходимо включить эту возможность, используя параметр :allow_destroy для accepts_nested_attributes_for:
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address, allow_destroy: true end
Теперь, когда вы используете элемент формы с параметром _destroy со значением, равным true, вы будете удалять связанную модель (например, 1, ‘1’, true или ‘true’):
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
Delete: <%= address_fields.check_box :_destroy %>
<% end %>
...
<% end %> Один ко многим
Рассмотрим класс Person, который возвращает массив экземпляров Project из метода чтения projects и реагирует на метод записи projects_attributes=:
class Person
def projects
[@project1, @project2]
end
def projects_attributes=(attributes)
# Process the attributes hash
end
end
Обратите внимание, что метод записи projects_attributes= фактически необходим для того, чтобы fields_for правильно идентифицировал :projects как коллекцию и правильно установил индексы в разметке формы.
Если проекты уже являются ассоциацией в Person, вы можете использовать accepts_nested_attributes_for для определения метода записи за вас:
class Person < ActiveRecord::Base has_many :projects accepts_nested_attributes_for :projects end
Теперь эту модель можно использовать с вложенным fields_for. Блок, переданный вложенному вызову fields_for, будет повторён для каждого экземпляра в коллекции:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
<% if project_fields.object.active? %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
...
<% end %> Также можно указать используемый экземпляр:
<%= form_with model: @person do |person_form| %>
...
<% @person.projects.each do |project| %>
<% if project.active? %>
<%= person_form.fields_for :projects, project do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
<% end %>
...
<% end %> Или коллекцию для использования:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects, @active_projects do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
...
<% end %> Если вы хотите удалить какие-либо связанные модели через форму, сначала необходимо включить эту возможность, используя параметр :allow_destroy для accepts_nested_attributes_for:
class Person < ActiveRecord::Base has_many :projects accepts_nested_attributes_for :projects, allow_destroy: true end
Это позволит указать, какие модели удалить в хэше атрибутов, добавив элемент формы для параметра _destroy со значением, равным true (например, 1, ‘1’, true или ‘true’):
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Delete: <%= project_fields.check_box :_destroy %>
<% end %>
...
<% end %> При использовании коллекции вы, возможно, захотите узнать индекс каждого объекта в массиве. Для этой цели доступен метод index в объекте FormBuilder.
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %> Обратите внимание, что fields_for автоматически сгенерирует скрытое поле для хранения идентификатора записи, если она отвечает запросу persisted?. Существуют ситуации, когда это скрытое поле не требуется, и вы можете передать include_id: false для предотвращения автоматического рендеринга скрытого поля fields_for.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1247
def file_field(object_name, method, options = {})
options = { include_hidden: multiple_file_field_include_hidden }.merge!(options)
Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
end Возвращает тег ввода для загрузки файла, настроенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, назначенного шаблону (идентифицируемого по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML в качестве атрибутов HTML-элемента, как показано в примере.
Использование этого метода внутри блока form_with установит кодировку содержащей формы на multipart/form-data.
Параметры
-
Создаёт стандартные атрибуты HTML для тега.
-
:disabled— Если установлено в true, пользователь не сможет использовать этот элемент ввода. -
:multiple— Если установлено в true, *в большинстве современных браузеров* пользователь сможет выбрать несколько файлов. -
:include_hidden— Когдаmultiple: trueиinclude_hidden: true, поле будет дополнено полем<input type="hidden">с пустым значением для поддержки отправки пустой коллекции файлов. -
:accept— Если установлено на один или несколько MIME-типов, пользователю будет предложен фильтр при выборе файла. Вам всё равно необходимо настроить валидацию модели.
Примеры
file_field(:user, :avatar) # => <input type="file" id="user_avatar" name="user[avatar]" /> file_field(:article, :image, multiple: true) # => <input type="file" id="article_image" name="article[image][]" multiple="multiple" /> file_field(:article, :attached, accept: 'text/html') # => <input accept="text/html" type="file" id="article_attached" name="article[attached]" /> file_field(:article, :image, accept: 'image/png,image/gif,image/jpeg') # => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" /> file_field(:attachment, :file, class: 'file_input') # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 435
def form_for(record, options = {}, &block)
raise ArgumentError, "Missing block" unless block_given?
case record
when String, Symbol
model = false
object_name = record
else
model = record
object = _object_for_form_builder(record)
raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
object_name = options[:as] || model_name_from_record_or_class(object).param_key
apply_form_for_options!(object, options)
end
remote = options.delete(:remote)
if remote && !embed_authenticity_token_in_remote_forms && options[:authenticity_token].blank?
options[:authenticity_token] = false
end
options[:model] = model
options[:scope] = object_name
options[:local] = !remote
options[:skip_default_ids] = false
options[:allow_method_names_outside_object] = options.fetch(:allow_method_names_outside_object, false)
form_with(**options, &block)
end Создаёт форму, которая позволяет пользователю создавать или обновлять атрибуты конкретного объекта модели.
Метод может использоваться несколькими слегка разными способами, в зависимости от того, насколько вы хотите полагаться на Rails для автоматического определения из модели, как следует построить форму. Для общего объекта модели форма может быть создана путём передачи form_for строки или символа, представляющего объект, который нас интересует:
<%= form_for :person do |f| %> First name: <%= f.text_field :first_name %><br /> Last name : <%= f.text_field :last_name %><br /> Biography : <%= f.text_area :biography %><br /> Admin? : <%= f.check_box :admin %><br /> <%= f.submit %> <% end %>
Переменная f, переданная в блок, представляет собой объект FormBuilder, который включает в себя знания об объекте модели, представленном :person переданным в form_for. Методы, определённые в FormBuilder, используются для генерации полей, связанных с этой моделью. Таким образом, например,
<%= f.text_field :first_name %>
расширяется до
<%= text_field :person, :first_name %>
что приводит к тегу HTML <input>, у которого атрибут name равен person[first_name]. Это означает, что при отправке формы значение, введённое пользователем, будет доступно в контроллере как params[:person][:first_name].
Для полей, сгенерированных таким способом с помощью FormBuilder, если :person также является именем переменной экземпляра @person, значение по умолчанию поля, отображаемое при первоначальном отображении формы (например, в ситуации редактирования существующего объекта), будет значением соответствующего атрибута @person.
Правый аргумент form_for - это необязательный хеш опций -
-
:url- URL, на который будет отправляться форма. Он может быть представлен так же, как значения, передаваемые вurl_forилиlink_to. Таким образом, вы можете напрямую использовать именованный маршрут. Когда модель представлена строкой или символом, как в примере выше, если опция:urlне указана, по умолчанию форма будет отправлена обратно на текущий URL (мы опишем ниже альтернативное использованиеform_forс ресурсоориентированной структурой, в котором URL не нужно явно указывать). -
:namespace- Пространство имён для вашей формы, чтобы гарантировать уникальность атрибутов id элементов формы. Атрибут пространства имён будет префиксным символом «_» в сгенерированном HTML id. -
:method- Метод, используемый при отправке формы, обычно «get» или «post». Если используется «patch», «put», «delete» или другой глагол, скрытый элемент с именем_methodдобавляется для имитации глагола над отправкой. -
:authenticity_token- Токен аутентификации для использования в форме. Используйте только в том случае, если вам нужно передать строку пользовательского токена аутентификации или не добавлять поле authenticity_token вообще (передавfalse). Дистанционные формы могут опустить встроенный токен аутентификации, установивconfig.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно, когда форма кешируется по фрагментам. Дистанционные формы получают токен аутентификации из тегаmeta, поэтому встраивание не нужно, если вы поддерживаете браузеры без JavaScript. -
:remote- Если установлено в значение true, это позволит драйверам Unobtrusive JavaScript управлять поведением отправки. -
:enforce_utf8- Если установлено в значение false, скрытый элемент с именем utf8 не выводится. -
:html- Необязательные HTML-атрибуты для тега формы.
Также обратите внимание, что form_for не создаёт исключительного пространства. По-прежнему возможно использовать как независимые методы FormHelper, так и методы из FormTagHelper. Например:
<%= form_for :person do |f| %> First name: <%= f.text_field :first_name %> Last name : <%= f.text_field :last_name %> Biography : <%= text_area :person, :biography %> Admin? : <%= check_box_tag "person[admin]", "1", @person.company.admin? %> <%= f.submit %> <% end %>
Это также работает для методов в FormOptionsHelper и DateHelper, которые предназначены для работы с объектом в качестве базового, как FormOptionsHelper#collection_select и DateHelper#datetime_select.
form_for с объектом модели
В примерах выше, объект для создания или редактирования был представлен символом, переданным в form_for, и мы отметили, что строка также может быть использована аналогичным образом. Однако также можно передать сам объект модели в form_for. Например, если @article - это существующий объект, который вы хотите отредактировать, вы можете создать форму, используя
<%= form_for @article do |f| %> ... <% end %>
Это работает практически так же, как описано ранее, с парой небольших исключений. Во-первых, префикс, используемый для именования элементов ввода в форме (следовательно, ключ, обозначающий их в хеше params ), фактически извлекается из класса объекта, например params[:article] , если класс объекта Article. Однако это можно переопределить, используя опцию :as, например -
<%= form_for(@person, as: :client) do |f| %> ... <% end %>
что приведёт к params[:client].
Во-вторых, значения полей, отображаемые при первоначальном отображении формы, берутся из атрибутов объекта, переданного в form_for, независимо от того, является ли объект переменной экземпляра. Например, если у нас есть локальная переменная article, представляющая существующий объект,
<%= form_for article do |f| %> ... <% end %>
сгенерирует форму с полями, начальное состояние которых отражает текущие значения атрибутов article.
Ресурсоориентированный стиль
В только что показанных примерах, хотя и не указано явно, нам всё ещё нужно использовать опцию :url для указания места отправки формы. Однако возможно дальнейшее упрощение, если объект, переданный в form_for, является ресурсом, т.е. соответствует набору RESTful маршрутов, например, определённых с помощью метода resources в config/routes.rb. В этом случае Rails просто выведет соответствующий URL из самого объекта. Например,
<%= form_for @article do |f| %> ... <% end %>
эквивалентно чему-то вроде:
<%= form_for @article, as: :article, url: article_path(@article), method: :patch, html: { class: "edit_article", id: "edit_article_45" } do |f| %>
...
<% end %> И для нового объекта
<%= form_for(Article.new) do |f| %> ... <% end %>
эквивалентно чему-то вроде:
<%= form_for @article, as: :article, url: articles_path, html: { class: "new_article", id: "new_article" } do |f| %>
...
<% end %> Однако вы всё ещё можете переопределить отдельные соглашения, например:
<%= form_for(@article, url: super_articles_path) do |f| %> ... <% end %>
Вы можете опустить атрибут action , передав url: false:
<%= form_for(@article, url: false) do |f| %> ... <% end %>
Вы также можете установить формат ответа, например так:
<%= form_for(@article, format: :json) do |f| %> ... <% end %>
Для маршрутов с пространствами имён, например admin_article_url:
<%= form_for([:admin, @article]) do |f| %> ... <% end %>
Если ваш ресурс имеет определённые ассоциации, например, вы хотите добавить комментарии к документу, при условии, что маршруты настроены корректно:
<%= form_for([@document, @comment]) do |f| %> ... <% end %>
Где @document = Document.find(params[:id]) и @comment = Comment.new.
Установка метода
Вы можете принудительно использовать полный набор HTTP-глаголов, установив
method: (:get|:post|:patch|:put|:delete)
в хеше опций. Если глагол не GET или POST, которые изначально поддерживаются HTML-формами, форма будет установлена в POST, а скрытый элемент, называемый _method, будет содержать предполагаемый глагол для интерпретации сервером.
Неявный JavaScript
Указание:
remote: true
в хеше опций создаёт форму, которая позволит драйверам неявного JavaScript изменять её поведение. Отправка формы будет работать так же, как обычная отправка, как это воспринимает сторона приёма (все элементы доступны в params).
Пример:
<%= form_for(@article, remote: true) do |f| %> ... <% end %>
Сгенерированный HTML для этого будет:
<form action='http://www.example.com' method='post' data-remote='true'> <input name='_method' type='hidden' value='patch' /> ... </form>
Установка HTML-опций
Вы можете задавать атрибуты данных напрямую, передавая хеш данных, но все остальные HTML-опции должны быть обернуты в ключ HTML. Пример:
<%= form_for(@article, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
...
<% end %> Сгенерированный HTML для этого будет:
<form action='http://www.example.com' method='post' data-behavior='autosave' name='go'> <input name='_method' type='hidden' value='patch' /> ... </form>
Удаление скрытых идентификаторов моделей
Метод form_for автоматически включает идентификатор модели в качестве скрытого поля в форме. Это используется для поддержания корреляции между данными формы и связанной с ней моделью. Некоторые системы ORM не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите иметь возможность отключить скрытый идентификатор.
В следующем примере модель Article имеет несколько Comments, хранящихся внутри неё в базе данных NoSQL, поэтому для комментариев нет первичного ключа.
Пример:
<%= form_for(@article) do |f| %>
<%= f.fields_for(:comments, include_id: false) do |cf| %>
...
<% end %>
<% end %> Настраиваемые билдеры форм
Вы также можете создавать формы, используя настраиваемый класс FormBuilder. Наследуйте класс FormBuilder и переопределите или определите некоторые дополнительные помощники, а затем используйте свой настраиваемый билдер. Например, предположим, что у вас есть помощник для автоматического добавления меток к элементам формы.
<%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.text_area :biography %>
<%= f.check_box :admin %>
<%= f.submit %>
<% end %> В этом случае, если вы используете это:
<%= render f %>
Рендер шаблона - people/_labelling_form, а локальная переменная, ссылающаяся на билдер формы, называется labelling_form.
Настраиваемый класс FormBuilder автоматически объединяется с опциями вложенного вызова fields_for, если явно не указано иначе.
Во многих случаях вы захотите обернуть всё вышеперечисленное в другом помощнике, поэтому вы можете сделать что-то вроде следующего:
def labelled_form_for(record_or_name_or_array, *args, &block) options = args.extract_options! form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block) end
Если вам не нужно прикреплять форму к экземпляру модели, ознакомьтесь с FormTagHelper#form_tag.
Форма для внешних ресурсов
При создании форм для внешних ресурсов иногда необходимо задать токен аутентификации или просто отобразить форму без него, например, когда вы отправляете данные на платёжный шлюз, и количество и типы полей могут быть ограничены.
Для задания токена аутентификации вам нужно передать параметр :authenticity_token
<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %> ... <% end %>
Если вы не хотите, чтобы поле токена аутентификации вообще отображалось, просто передайте false:
<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %> ... <% end %>
# File actionview/lib/action_view/helpers/form_helper.rb, line 755
def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block)
ActionView.deprecator.warn("Passing nil to the :model argument is deprecated and will raise in Rails 8.0") if model.nil?
options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
if model
if url != false
url ||= if format.nil?
polymorphic_path(model, {})
else
polymorphic_path(model, format: format)
end
end
model = convert_to_model(_object_for_form_builder(model))
scope ||= model_name_from_record_or_class(model).param_key
end
if block_given?
builder = instantiate_builder(scope, model, options)
output = capture(builder, &block)
options[:multipart] ||= builder.multipart?
html_options = html_options_for_form_with(url, model, **options)
form_tag_with_body(html_options, output)
else
html_options = html_options_for_form_with(url, model, **options)
form_tag_html(html_options)
end
end Создаёт тег формы на основе смешивания URL-адресов, областей или моделей.
# Using just a URL: <%= form_with url: articles_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="title" /> </form> # With an intentionally empty URL: <%= form_with url: false do |form| %> <%= form.text_field :title %> <% end %> # => <form method="post"> <input type="text" name="title" /> </form> # Adding a scope prefixes the input field names: <%= form_with scope: :article, url: articles_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="article[title]" /> </form> # Using a model infers both the URL and scope: <%= form_with model: Article.new do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="article[title]" /> </form> # An existing model makes an update form and fills out field values: <%= form_with model: Article.first do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles/1" method="post"> <input type="hidden" name="_method" value="patch" /> <input type="text" name="article[title]" value="<the title of the article>" /> </form> # Though the fields don't have to correspond to model attributes: <%= form_with model: Cat.new do |form| %> <%= form.text_field :cats_dont_have_gills %> <%= form.text_field :but_in_forms_they_can %> <% end %> # => <form action="/cats" method="post"> <input type="text" name="cat[cats_dont_have_gills]" /> <input type="text" name="cat[but_in_forms_they_can]" /> </form>
Параметры форм доступны в контроллерах в соответствии с их вложенностью. Так, поля с именами title и article[title] доступны как params[:title] и params[:article][:title] соответственно.
Для простоты сравнения в примерах выше отсутствует кнопка отправки, а также автоматически сгенерированные скрытые поля, которые обеспечивают поддержку UTF-8 и добавляют токен аутентификации, необходимый для защиты от подделки межсайтовых запросов.
Ориентированный на ресурсы стиль
Во многих из показанных примеров :model, передаваемый в form_with — это ресурс. Он соответствует набору маршрутов RESTful, скорее всего, определённых с помощью resources в config/routes.rb.
Таким образом, при передаче такой записи модели Rails выводит URL-адрес и метод.
<%= form_with model: @article do |form| %> ... <% end %>
эквивалентно чему-то вроде:
<%= form_with scope: :article, url: article_path(@article), method: :patch do |form| %> ... <% end %>
А для новой записи
<%= form_with model: Article.new do |form| %> ... <% end %>
эквивалентно чему-то вроде:
<%= form_with scope: :article, url: articles_path do |form| %> ... <% end %>
Параметры form_with
-
:url— URL-адрес, куда отправляется форма. Аналогично значениям, передаваемым вurl_forилиlink_to. Например, вы можете использовать непосредственно именованный маршрут. Когда:scopeпередаётся без:urlформа отправляется на текущий URL. -
:method— метод, используемый при отправке формы, обычно «get» или «post». Если «patch», «put», «delete» или другой глагол, добавляется скрытое поле с именем_method, чтобы смоделировать глагол над отправкой POST. -
:format— формат маршрута, на который отправляется форма. Полезно при отправке на другой тип ресурса, например:json. Пропускается, если передаётся:url. -
:scope— область, с которой префикс добавляется к именам полей ввода, и таким образом, как отправленные параметры группируются в контроллерах. -
:namespace— пространство имён для вашей формы, чтобы гарантировать уникальность атрибутов id элементов формы. Атрибут пространства имён будет предваряться подчёркиванием в сгенерированном HTML-id. -
:model— объект модели, чтобы определить:urlи:scopeпо нему, плюс заполнить значения полей ввода. Так, если атрибутtitleустановлен в «Ahoy!», то значение поля вводаtitleбудет «Ahoy!». Если модель является новой записью, генерируется форма создания, а если существующей — форма обновления. Передайте:scopeили:urlдля переопределения значений по умолчанию. Например, преобразоватьparams[:article]вparams[:blog]. -
:authenticity_token— токен аутентификации для использования в форме. Переопределите его с помощью пользовательского токена аутентификации или передайтеfalseдля пропуска поля токена аутентификации. Полезно при отправке на внешний ресурс, такой как платёжный шлюз, который может ограничить допустимые поля. Отдалённые формы могут опустить встроенный токен аутентификации, установивconfig.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно при кэшировании фрагментов формы. Отдалённые формы получают токен аутентификации из тегаmeta, поэтому встраивание не нужно, если вы поддерживаете браузеры без JavaScript. -
:local— использовать стандартную HTTP-отправку формы. Когда установленоtrue, форма отправляется через стандартный HTTP. Когда установленоfalse, форма отправляется как «удалённая форма», которая обрабатывается Rails UJS как XHR. Если не указано, поведение определяется изconfig.action_view.form_with_generates_remote_forms, где значение конфигурации на самом деле является обратным тому, каким было бы значениеlocal. Начиная с Rails 6.1, этот параметр конфигурации по умолчанию равенfalse(что эквивалентно передачеlocal: true). В предыдущих версиях Rails этот параметр конфигурации по умолчанию равенtrue(эквивалентно передачеlocal: false). -
:skip_enforcing_utf8— если установлено в true, скрытый элемент ввода с именем utf8 не выводится. -
:builder— переопределить объект, используемый для построения формы. -
:id— необязательный атрибут HTML id. -
:class— необязательный атрибут HTML class. -
:data— необязательные атрибуты данных HTML. -
:html— другие необязательные атрибуты HTML для тега формы.
Примеры
При отсутствии блока, form_with генерирует только открывающий тег формы.
<%= form_with(model: @article, url: super_articles_path) %> <%= form_with(model: @article, scope: :blog) %> <%= form_with(model: @article, format: :json) %> <%= form_with(model: @article, authenticity_token: false) %> # Disables the token.
Для именованных маршрутов, таких как admin_article_url:
<%= form_with(model: [ :admin, @article ]) do |form| %> ... <% end %>
Если ваш ресурс имеет определённые ассоциации, например, вы хотите добавить комментарии к документу при условии, что маршруты настроены правильно:
<%= form_with(model: [ @document, Comment.new ]) do |form| %> ... <% end %>
Где @document = Document.find(params[:id]).
Смешивание с другими помощниками форм
Хотя form_with использует объект FormBuilder, можно смешивать и сопоставлять автономные методы FormHelper и методы из FormTagHelper:
<%= form_with scope: :person do |form| %> <%= form.text_field :first_name %> <%= form.text_field :last_name %> <%= text_area :person, :biography %> <%= check_box_tag "person[admin]", "1", @person.company.admin? %> <%= form.submit %> <% end %>
То же самое относится к методам в FormOptionsHelper и DateHelper, предназначенным для работы с объектом в качестве базы, например FormOptionsHelper#collection_select и DateHelper#datetime_select.
Установка метода
Вы можете принудительно заставить форму использовать весь набор HTTP-глаголов, установив
method: (:get|:post|:patch|:put|:delete)
в хэше параметров. Если глагол не GET или POST, которые нативно поддерживаются HTML-формами, форма будет установлена на POST, и скрытый элемент ввода с именем _method будет содержать предназначенный глагол для интерпретации сервером.
Установка атрибутов HTML
Вы можете установить атрибуты данных непосредственно в хэше данных, но атрибуты HTML помимо id и class должны быть обернуты в ключ HTML:
<%= form_with(model: @article, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
...
<% end %> генерирует
<form action="/articles/123" method="post" data-behavior="autosave" name="go"> <input name="_method" type="hidden" value="patch" /> ... </form>
Удаление скрытых id моделей
Метод form_with автоматически включает id модели в качестве скрытого поля в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите отключить скрытый идентификатор.
В следующем примере модель Article имеет несколько комментариев, хранящихся в ней в базе данных NoSQL, поэтому нет первичного ключа для комментариев.
<%= form_with(model: @article) do |form| %>
<%= form.fields(:comments, skip_id: true) do |fields| %>
...
<% end %>
<% end %> Настраиваемые строители форм
Вы также можете создавать формы с помощью настроенного класса FormBuilder. Наследуйте от FormBuilder и переопределите или определите несколько дополнительных помощников, а затем используйте свой настроенный строитель. Например, предположим, что вы создали помощник, который автоматически добавляет метки к полям ввода формы.
<%= form_with model: @person, url: { action: "create" }, builder: LabellingFormBuilder do |form| %>
<%= form.text_field :first_name %>
<%= form.text_field :last_name %>
<%= form.text_area :biography %>
<%= form.check_box :admin %>
<%= form.submit %>
<% end %> В этом случае, если вы используете:
<%= render form %>
Рендер шаблона — people/_labelling_form , а локальная переменная, ссылающаяся на строитель формы, называется labelling_form.
Настраиваемый класс FormBuilder автоматически объединяется с параметрами вложенного вызова fields , если он явно не задан.
Во многих случаях вам нужно будет обернуть это в другой помощник, поэтому вы можете сделать что-то вроде следующего:
def labelled_form_with(**options, &block) form_with(**options.merge(builder: LabellingFormBuilder), &block) end
Возвращает тег скрытого элемента ввода, настроенный для доступа к указанному атрибуту (идентифицированному по method) объекта, присвоенного шаблону (идентифицированного по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены к HTML в качестве атрибута HTML-элемента, как показано в примере.
Примеры
hidden_field(:signup, :pass_confirm)
# => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
hidden_field(:article, :tag_list)
# => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="#{@article.tag_list}" />
hidden_field(:user, :token)
# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1151 def label(object_name, method, content_or_options = nil, options = nil, &block) Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) end
Возвращает тег метки, настроенный для маркировки поля ввода для указанного атрибута (идентифицированного по method) объекта, присвоенного шаблону (идентифицированного по object). Текст метки будет по умолчанию равен имени атрибута, если не будет найдено перевода в текущем локали I18n (через helpers.label.<modelname>.<attribute>) или вы его явно не укажете. Дополнительные параметры тега метки могут быть переданы в виде хэша с options. Эти параметры будут добавлены к HTML в качестве атрибута HTML-элемента, как показано в примере, за исключением параметра :value, который предназначен для привязки меток к тегам radio_button (где значение используется в идентификаторе тега ввода).
Примеры
label(:article, :title) # => <label for="article_title">Title</label>
Вы можете локализовать свои метки на основе имён модели и атрибутов. Например, вы можете определить следующее в своём локали (например, en.yml)
helpers:
label:
article:
body: "Write your entire text here" Что затем приведёт к
label(:article, :body) # => <label for="article_body">Write your entire text here</label>
Локализация также может быть основана исключительно на переводе имени атрибута (если вы используете ActiveRecord):
activerecord:
attributes:
article:
cost: "Total cost" label(:article, :cost)
# => <label for="article_cost">Total cost</label>
label(:article, :title, "A short title")
# => <label for="article_title">A short title</label>
label(:article, :title, "A short title", class: "title_label")
# => <label for="article_title" class="title_label">A short title</label>
label(:article, :privacy, "Public Article", value: "public")
# => <label for="article_privacy_public">Public Article</label>
label(:article, :cost) do |translation|
content_tag(:span, translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
label(:article, :cost) do |builder|
content_tag(:span, builder.translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
label(:article, :terms) do
raw('Accept <a href="/terms">Terms</a>.')
end
# => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1531
def month_field(object_name, method, options = {})
Tags::MonthField.new(object_name, method, self, options).render
end Возвращает text_field типа «месяц».
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="month" />
Значение по умолчанию генерируется путем вызова strftime с «%Y-%m» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.
@user.born_on = Date.new(1984, 1, 27)
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1575
def number_field(object_name, method, options = {})
Tags::NumberField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «число».
Параметры
Поддерживает те же параметры, что и FormTagHelper#number_field_tag.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1196
def password_field(object_name, method, options = {})
Tags::PasswordField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «пароль», настроенный для доступа к указанному атрибуту (идентифицированному как method) объекта, присвоенного шаблону (идентифицированного как object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибуты HTML-элемента, как показано в примере. По соображениям безопасности, поле по умолчанию пустое; передайте значение через options, если это не нужно.
Примеры
password_field(:login, :pass, size: 20)
# => <input type="password" id="login_pass" name="login[pass]" size="20" />
password_field(:account, :secret, class: "form_input", value: @account.secret)
# => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />
password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
# => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>
password_field(:account, :pin, size: 20, class: 'form_input')
# => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
алиас для telephone_field
# File actionview/lib/action_view/helpers/form_helper.rb, line 1367
def radio_button(object_name, method, tag_value, options = {})
Tags::RadioButton.new(object_name, method, self, tag_value, options).render
end Возвращает тег радиокнопки для доступа к указанному атрибуту (идентифицированному как method) объекта, присвоенного шаблону (идентифицированному как object). Если текущее значение method равно tag_value, радиокнопка будет отмечена.
Чтобы принудительно установить радиокнопку, передайте checked: true в хэш options. Вы также можете передать там HTML-параметры.
# Let's say that @article.category returns "rails":
radio_button("article", "category", "rails")
radio_button("article", "category", "java")
# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
# <input type="radio" id="article_category_java" name="article[category]" value="java" />
# Let's say that @user.receive_newsletter returns "no":
radio_button("user", "receive_newsletter", "yes")
radio_button("user", "receive_newsletter", "no")
# => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
# <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1584
def range_field(object_name, method, options = {})
Tags::RangeField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «диапазон».
Параметры
Поддерживает те же параметры, что и FormTagHelper#range_field_tag.
# File actiontext/app/helpers/action_text/tag_helper.rb, line 86
def rich_text_area(object_name, method, options = {})
Tags::ActionText.new(object_name, method, self, options).render
end Возвращает тег trix-editor, который инициализирует JavaScript-редактор Trix, а также скрытое поле, в которое Trix будет записывать изменения, поэтому содержимое будет отправлено при отправке формы.
Параметры
-
:class- По умолчанию «trix-content», что обеспечивает применение стандартной стилизации. -
:value- Добавляет значение по умолчанию в тег HTML-ввода. -
[:data][:direct_upload_url]- По умолчаниюrails_direct_uploads_url. -
[:data][:blob_url_template]- По умолчаниюrails_service_blob_url(":signed_id", ":filename").
Пример
rich_text_area :message, :content # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1"> # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor> rich_text_area :message, :content, value: "<h1>Default message</h1>" # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>"> # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1398
def search_field(object_name, method, options = {})
Tags::SearchField.new(object_name, method, self, options).render
end Возвращает элемент ввода типа «поиск» для доступа к указанному атрибуту (идентифицированному как method) объекта, присвоенного шаблону (идентифицированному как object_name). Элементы ввода типа «поиск» могут отображаться по-разному в разных браузерах.
search_field(:user, :name) # => <input id="user_name" name="user[name]" type="search" /> search_field(:user, :name, autosave: false) # => <input autosave="false" id="user_name" name="user[name]" type="search" /> search_field(:user, :name, results: 3) # => <input id="user_name" name="user[name]" results="3" type="search" /> # Assume request.host returns "www.example.com" search_field(:user, :name, autosave: true) # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" /> search_field(:user, :name, onsearch: true) # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" /> search_field(:user, :name, autosave: false, onsearch: true) # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" /> search_field(:user, :name, autosave: true, onsearch: true) # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1407
def telephone_field(object_name, method, options = {})
Tags::TelField.new(object_name, method, self, options).render
end Возвращает text_field типа «телефон».
telephone_field("user", "phone")
# => <input id="user_phone" name="user[phone]" type="tel" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1277
def text_area(object_name, method, options = {})
Tags::TextArea.new(object_name, method, self, options).render
end Возвращает тег textarea, настроенный для доступа к указанному атрибуту (идентифицированному как method) объекта, присвоенного шаблону (идентифицированному как object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options.
Примеры
text_area(:article, :body, cols: 20, rows: 40)
# => <textarea cols="20" rows="40" id="article_body" name="article[body]">
# #{@article.body}
# </textarea>
text_area(:comment, :text, size: "20x30")
# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
# #{@comment.text}
# </textarea>
text_area(:application, :notes, cols: 40, rows: 15, class: 'app_input')
# => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input">
# #{@application.notes}
# </textarea>
text_area(:entry, :body, size: "20x20", disabled: 'disabled')
# => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
# #{@entry.body}
# </textarea>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1175
def text_field(object_name, method, options = {})
Tags::TextField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «текст», настроенный для доступа к указанному атрибуту (идентифицированному как method) объекта, присвоенного шаблону (идентифицированному как object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибуты HTML-элемента, как показано в примере.
Примеры
text_field(:article, :title, size: 20)
# => <input type="text" id="article_title" name="article[title]" size="20" value="#{@article.title}" />
text_field(:article, :title, class: "create_input")
# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" class="create_input" />
text_field(:article, :title, maxlength: 30, class: "title_input")
# => <input type="text" id="article_title" name="article[title]" maxlength="30" size="30" value="#{@article.title}" class="title_input" />
text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
# => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>
text_field(:snippet, :code, size: 20, class: 'code_input')
# => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1477
def time_field(object_name, method, options = {})
Tags::TimeField.new(object_name, method, self, options).render
end Возвращает text_field типа «время».
Значение по умолчанию генерируется путем вызова strftime с «%T.%L» на значении объекта. Если вы передаете include_seconds: false, оно будет отформатировано путем вызова strftime с «%H:%M» на значении объекта. Также можно переопределить это, передав параметр «value».
Параметры
Поддерживает те же параметры, что и FormTagHelper#time_field_tag.
Примеры
time_field("task", "started_at")
# => <input id="task_started_at" name="task[started_at]" type="time" />
Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.
time_field("task", "started_at", min: Time.now)
# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
В качестве альтернативы, вы можете передать строку, отформатированную как ISO8601-время, в качестве значений для «min» и «max».
time_field("task", "started_at", min: "01:00:00")
# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
По умолчанию, предоставленное время будет отформатировано, включая секунды. Вы можете отобразить только час и минуту, передав include_seconds: false. Некоторые браузеры будут отображать более простой интерфейс, если вы исключите секунды в формате метки времени.
time_field("task", "started_at", value: Time.now, include_seconds: false)
# => <input id="task_started_at" name="task[started_at]" type="time" value="01:00" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1557
def url_field(object_name, method, options = {})
Tags::UrlField.new(object_name, method, self, options).render
end Возвращает text_field типа «URL».
url_field("user", "homepage")
# => <input id="user_homepage" name="user[homepage]" type="url" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1548
def week_field(object_name, method, options = {})
Tags::WeekField.new(object_name, method, self, options).render
end Возвращает text_field типа “week”.
week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="week" />
Значение по умолчанию генерируется путём вызова strftime с “%Y-W%W” для значения объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.
@user.born_on = Date.new(1984, 5, 12)
week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-W19" />
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.