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