класс ActionView::Helpers::FormBuilder
Формогенератор Action View
Объект FormBuilder связан с конкретным объектом модели и позволяет генерировать поля, связанные с этим объектом модели. Объект FormBuilder передаётся в качестве результата вызова form_with или fields_for. Например:
<%= form_with model: @person do |person_form| %> Name: <%= person_form.text_field :name %> Admin: <%= person_form.checkbox :admin %> <% end %>
В данном блоке объект FormBuilder передаётся как переменная person_form. Это позволяет генерировать поля text_field и checkbox путём вызова одноимённых методов, которые изменяют шаблон и связывают объект модели @person с формой.
Объект FormBuilder можно рассматривать как прокси для методов модуля FormHelper. Однако, этот класс позволяет вызывать методы с объектом модели, для которого создаётся форма.
Вы можете создать свои пользовательские шаблоны FormBuilder, наследуя этот класс. Например:
class MyFormBuilder < ActionView::Helpers::FormBuilder
def div_radio_button(method, tag_value, options = {})
@template.content_tag(:div,
@template.radio_button(
@object_name, method, tag_value, objectify_options(options)
)
)
end
end
Вышеприведённый код создаёт новый метод div_radio_button, который обёртывает новый радио-кнопку в div. Обратите внимание, что при передаче опций необходимо вызвать objectify_options, чтобы объект модели был корректно передан в метод. Если objectify_options не вызывается, новый помощник не будет связан с моделью.
Код div_radio_button из примера выше теперь можно использовать следующим образом:
<%= form_with model: @person, :builder => MyFormBuilder do |f| %> I am a child: <%= f.div_radio_button(:admin, "child") %> I am an adult: <%= f.div_radio_button(:admin, "adult") %> <% end -%>
Стандартный набор методов-помощников для создания форм находится в атрибуте класса field_helpers.
Атрибуты
Открытые методы класса
# File actionview/lib/action_view/helpers/form_helper.rb, line 1708 def self._to_partial_path @_to_partial_path ||= name.demodulize.underscore.sub!(/_builder$/, "") end
# File actionview/lib/action_view/helpers/form_helper.rb, line 1720
def initialize(object_name, object, template, options)
@nested_child_index = {}
@object_name, @object, @template, @options = object_name, object, template, options
@default_options = @options ? @options.slice(:index, :namespace, :skip_default_ids, :allow_method_names_outside_object) : {}
@default_html_options = @default_options.except(:skip_default_ids, :allow_method_names_outside_object)
convert_to_legacy_options(@options)
if @object_name&.end_with?("[]")
if (object ||= @template.instance_variable_get("@#{@object_name[0..-3]}")) && object.respond_to?(:to_param)
@auto_index = object.to_param
else
raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
end
end
@multipart = nil
@index = options[:index] || options[:child_index]
end Методы публичного экземпляра
# File actionview/lib/action_view/helpers/form_helper.rb, line 2649
def button(value = nil, options = {}, &block)
case value
when Hash
value, options = nil, value
when Symbol
value, options = nil, { name: field_name(value), id: field_id(value) }.merge!(options.to_h)
end
value ||= submit_default_value
if block_given?
value = @template.capture { yield(value) }
end
formmethod = options[:formmethod]
if formmethod.present? && !/post|get/i.match?(formmethod) && !options.key?(:name) && !options.key?(:value)
options.merge! formmethod: :post, name: "_method", value: formmethod
end
@template.button_tag(value, options)
end Добавляет кнопку отправки для данной формы. При отсутствии значения проверяет, является ли объект новым ресурсом, чтобы создать соответствующую метку:
<%= form_with model: @article do |f| %> <%= f.button %> <% end %>
В приведённом примере, если @article является новой записью, будет использована метка «Создать статью»; в противном случае — «Обновить статью».
Эти метки можно настроить с помощью I18n по ключу helpers.submit (такому же, как у вспомогательной функции submit) и с использованием %{model} для интерполяции перевода:
en:
helpers:
submit:
create: "Create a %{model}"
update: "Confirm changes to %{model}" Также ищется ключ, специфичный для данного объекта:
en:
helpers:
submit:
article:
create: "Add %{model}" Примеры
button("Create article")
# => <button name='button' type='submit'>Create article</button>
button(:draft, value: true)
# => <button id="article_draft" name="article[draft]" value="true" type="submit">Create article</button>
button do
content_tag(:strong, 'Ask me!')
end
# => <button name='button' type='submit'>
# <strong>Ask me!</strong>
# </button>
button do |text|
content_tag(:strong, text)
end
# => <button name='button' type='submit'>
# <strong>Create article</strong>
# </button>
button(:draft, value: true) do
content_tag(:strong, "Save as draft")
end
# => <button id="article_draft" name="article[draft]" value="true" type="submit">
# <strong>Save as draft</strong>
# </button>
# File actionview/lib/action_view/helpers/form_helper.rb, line 2473
def checkbox(method, options = {}, checked_value = "1", unchecked_value = "0")
@template.checkbox(@object_name, method, objectify_options(options), checked_value, unchecked_value)
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 гласит, что неотмеченные checkbox не успешны, и поэтому веб-браузеры их не отправляют. К сожалению, это создаёт проблему: если у модели Invoice есть флаг paid, и в форме редактирования платёжного счета пользователь снимит его, параметр paid не будет отправлен. Поэтому любой идиом массовой присваивания, такой как
@invoice.update(params[:invoice])
не обновит флаг.
Чтобы избежать этого, помощник генерирует вспомогательное скрытое поле перед каждым checkbox. Скрытое поле имеет такое же имя, и его атрибуты имитируют неотмеченный checkbox.
Таким образом, клиент отправляет либо только скрытое поле (что указывает, что checkbox не отмечен), либо оба поля. Поскольку спецификация HTML гласит, что пары ключ/значение должны отправляться в том же порядке, в котором они появляются в форме, а извлечение параметров получает последнее вхождение любого повторяющегося ключа в строке запроса, это работает для обычных форм.
К сожалению, это решение не работает, когда checkbox находится внутри параметра, подобного массиву, как в
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> <%= form.checkbox :paid %> ... <% end %>
потому что Rails именно повторяющиеся имена параметров предназначены для различения элементов массива. Для каждого элемента с отмеченным checkbox вы получаете дополнительный "призрачный" элемент только с этим атрибутом, присвоенным «0».
В этом случае предпочтительнее либо использовать checkbox_tag , либо использовать хэши вместо массивов.
Примеры
# Let's say that @article.validated? is 1:
checkbox("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":
checkbox("gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
# <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
# Let's say that @eula.accepted is "no":
checkbox("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_options_helper.rb, line 909
def collection_checkboxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
@template.collection_checkboxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
end Оборачивает ActionView::Helpers::FormOptionsHelper#collection_checkboxes для билдеров форм:
<%= form_with model: @post do |f| %> <%= f.collection_checkboxes :author_ids, Author.all, :id, :name_with_initial %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 922
def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
@template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
end Оборачивает ActionView::Helpers::FormOptionsHelper#collection_radio_buttons для билдеров форм:
<%= form_with model: @post do |f| %> <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 861
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
@template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options))
end Оборачивает ActionView::Helpers::FormOptionsHelper#collection_select для билдеров форм:
<%= form_with model: @post do |f| %> <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1843
Оборачивает ActionView::Helpers::FormHelper#color_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.color_field :favorite_color %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1895
Оборачивает ActionView::Helpers::FormHelper#date_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.date_field :born_on %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/date_helper.rb, line 1237
def date_select(method, options = {}, html_options = {})
@template.date_select(@object_name, method, objectify_options(options), html_options)
end Оборачивает ActionView::Helpers::DateHelper#date_select для билдеров форм:
<%= form_with model: @person do |f| %> <%= f.date_select :birth_date %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1921
Оборачивает ActionView::Helpers::FormHelper#datetime_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.datetime_field :graduation_day %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1934
Оборачивает ActionView::Helpers::FormHelper#datetime_local_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.datetime_local_field :graduation_day %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/date_helper.rb, line 1261
def datetime_select(method, options = {}, html_options = {})
@template.datetime_select(@object_name, method, objectify_options(options), html_options)
end Оборачивает ActionView::Helpers::DateHelper#datetime_select для билдеров форм:
<%= form_with model: @person do |f| %> <%= f.datetime_select :last_request_at %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1986
Оборачивает ActionView::Helpers::FormHelper#email_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.email_field :address %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1777 def field_id(method, *suffixes, namespace: @options[:namespace], index: @options[:index]) @template.field_id(@object_name, method, *suffixes, namespace: namespace, index: index) end
Генерирует значение атрибута HTML id для заданного поля.
Возвращает значение, сгенерированное FormBuilder для заданного имени атрибута.
<%= form_with model: @article do |f| %>
<%= f.label :title %>
<%= f.text_field :title, aria: { describedby: f.field_id(:title, :error) } %>
<%= tag.span("is blank", id: f.field_id(:title, :error) %>
<% end %> В приведённом примере элемент <input type="text">, созданный вызовом FormBuilder#text_field, объявляет атрибут aria-describedby, ссылающийся на элемент <span>, используя общий корень id (в данном случае article_title).
# File actionview/lib/action_view/helpers/form_helper.rb, line 1797
def field_name(method, *methods, multiple: false, index: @options[:index])
object_name = @options.fetch(:as) { @object_name }
@template.field_name(object_name, method, *methods, index: index, multiple: multiple)
end Генерирует значение атрибута HTML name для заданного имени и поля.
Возвращает значение, сгенерированное FormBuilder для заданного имени атрибута.
<%= form_with model: @article do |f| %> <%= f.text_field :title, name: f.field_name(:title, :subtitle) %> <%# => <input type="text" name="article[title][subtitle]"> %> <% end %> <%= form_with model: @article do |f| %> <%= f.text_field :tag, name: f.field_name(:tag, multiple: true) %> <%# => <input type="text" name="article[tag][]"> %> <% end %>
# File actionview/lib/action_view/helpers/form_helper.rb, line 2327 def fields(scope = nil, model: nil, **options, &block) options[:allow_method_names_outside_object] = true options[:skip_default_ids] = !FormHelper.form_with_generates_ids convert_to_legacy_options(options) fields_for(scope || model, model, options, &block) end
См. документацию по методу помощника ActionView::Helpers::FormHelper#fields.
# File actionview/lib/action_view/helpers/form_helper.rb, line 2289
def fields_for(record_name, record_object = nil, fields_options = nil, &block)
fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
fields_options ||= {}
fields_options[:builder] ||= options[:builder]
fields_options[:namespace] = options[:namespace]
fields_options[:parent_builder] = self
case record_name
when String, Symbol
if nested_attributes_association?(record_name)
return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
end
else
record_object = @template._object_for_form_builder(record_name)
record_name = model_name_from_record_or_class(record_object).param_key
end
object_name = @object_name
index = if options.has_key?(:index)
options[:index]
elsif defined?(@auto_index)
object_name = object_name.to_s.delete_suffix("[]")
@auto_index
end
record_name = if index
"#{object_name}[#{index}][#{record_name}]"
elsif record_name.end_with?("[]")
"#{object_name}[#{record_name[0..-3]}][#{record_object.id}]"
else
"#{object_name}[#{record_name}]"
end
fields_options[:child_index] = index
@template.fields_for(record_name, record_object, fields_options, &block)
end Создаёт область видимости вокруг конкретного объекта модели, например, form_with, но не создаёт теги формы сами по себе. Это делает fields_for подходящим для указания дополнительных объектов модели в той же форме.
Хотя использование и назначение fields_for аналогично form_with , его сигнатура метода немного отличается. Как и 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.checkbox :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.checkbox :admin %> <% end %>
…в котором случае, если :permission также является именем переменной экземпляра @permission, начальное состояние поля ввода будет отражать значение атрибута переменной @permission.admin.
В качестве альтернативы можно передать сам объект модели (если первый аргумент не является строкой или символом, fields_for поймёт, что имя опущено) —
<%= fields_for @person.permission do |permission_fields| %> Admin?: <%= permission_fields.checkbox :admin %> <% end %>
и fields_for выведет требуемое имя поля из класса объекта модели, например, если @person.permission, является экземпляром класса Permission, поле всё равно будет называться permission[admin].
Примечание: Это также работает для методов в FormOptionsHelper и DateHelper, которые предназначены для работы с объектом в качестве базы, например, FormOptionsHelper#collection_select и DateHelper#datetime_select.
fields_for пытается быть умным по отношению к параметрам, но может быть сбит с толку, если переданы как параметр имени, так и значения, и переданное значение имеет форму параметра опций Hash. Чтобы устранить неоднозначность, явно передайте параметр опций Hash, даже если он пустой.
<%= form_with model: @person do |person_form| %>
...
<%= fields_for :permission, @person.permission, {} do |permission_fields| %>
Admin?: <%= checkbox_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
<% end %>
...
<% end %> Примеры вложенных атрибутов
Когда объект, принадлежащий текущей области видимости, имеет вложенный атрибут-писатель для определённого атрибута, 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.checkbox :_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.checkbox :_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 автоматически сгенерирует скрытое поле для хранения идентификатора записи. Существуют ситуации, когда это скрытое поле не требуется, и вы можете передать include_id: false чтобы предотвратить автоматическое рендеринг fields_for.
# File actionview/lib/action_view/helpers/form_helper.rb, line 2557
def file_field(method, options = {})
self.multipart = true
@template.file_field(@object_name, method, objectify_options(options))
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">с пустым значением для поддержки отправки пустого набора файлов. Посколькуinclude_hiddenпо умолчанию будетconfig.active_storage.multiple_file_field_include_hidden, если вы не укажетеinclude_hidden, вам необходимо передатьinclude_hidden: falseдля предотвращения отправки пустого набора файлов при передачеmultiple: true. -
:accept- Если установлено на один или несколько MIME-типов, пользователю будет предложен фильтр при выборе файла. Вам всё равно нужно настроить валидацию модели.
Примеры
# Let's say that @user has avatar: file_field(:avatar) # => <input type="file" id="user_avatar" name="user[avatar]" /> # Let's say that @article has image: file_field(:image, :multiple => true) # => <input type="file" id="article_image" name="article[image][]" multiple="multiple" /> # Let's say that @article has attached: file_field(:attached, accept: 'text/html') # => <input accept="text/html" type="file" id="article_attached" name="article[attached]" /> # Let's say that @article has image: file_field(:image, accept: 'image/png,image/gif,image/jpeg') # => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" /> # Let's say that @attachment has file: file_field(:file, class: 'file_input') # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 873
def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
@template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_html_options.merge(html_options))
end Оборачивает ActionView::Helpers::FormOptionsHelper#grouped_collection_select для билдеров форм:
<%= form_with model: @city do |f| %> <%= f.grouped_collection_select :country_id, @continents, :countries, :name, :id, :name %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
Возвращает тег скрытого элемента ввода, настроенный для доступа к указанному атрибуту (определяемому method) объекта, присвоенного шаблону (определяемому object). Дополнительные параметры тега ввода можно передать в виде хэша с options. Эти параметры будут добавлены к HTML в виде атрибутов HTML-элемента, как показано в примере.
Примеры
# Let's say that @signup.pass_confirm returns true: hidden_field(:pass_confirm) # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="true" /> # Let's say that @article.tag_list returns "blog, ruby": hidden_field(:tag_list) # => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="blog, ruby" /> # Let's say that @user.token returns "abcde": hidden_field(:token) # => <input type="hidden" id="user_token" name="user[token]" value="abcde" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1757 def id options.dig(:html, :id) || options[:id] end
Генерирует значение атрибута HTML id.
Возвращает значение атрибута id элемента <form>.
<%= form_with model: @article do |f| %>
<%# ... %>
<% content_for :sticky_footer do %>
<%= form.button(form: f.id) %>
<% end %>
<% end %> В приведённом примере область содержимого :sticky_footer будет существовать вне элемента <form>. Объявив атрибут HTML form, мы подсказываем браузеру, что сгенерированный элемент <button> должен обрабатываться как кнопка отправки элемента <form>, независимо от его расположения в DOM.
# File actionview/lib/action_view/helpers/form_helper.rb, line 2404
def label(method, text = nil, options = {}, &block)
@template.label(@object_name, method, text, objectify_options(options), &block)
end Возвращает тег метки, настроенный для маркировки поля ввода для указанного атрибута (определяемого method) объекта, присвоенного шаблону (определяемого object). Текст метки по умолчанию соответствует имени атрибута, если нет перевода в текущем локализованном файле I18n (через helpers.label.<modelname>.<attribute>) или если вы его явно не указываете. Дополнительные параметры тега метки можно передать в виде хэша с options. Эти параметры будут добавлены к HTML в виде атрибутов HTML-элемента, как в приведённом примере, за исключением параметра :value, который предназначен для целевой маркировки меток для тегов radio_button (где значение используется в ID тега ввода).
Примеры
label(:title) # => <label for="article_title">Title</label>
Вы можете локализовать метки на основе модели и имени атрибута. Например, вы можете определить следующее в своём локализованном файле (например, en.yml)
helpers:
label:
article:
body: "Write your entire text here" Что затем приведёт к
label(:body) # => <label for="article_body">Write your entire text here</label>
Локализация также может быть основана исключительно на переводе имени атрибута (если вы используете ActiveRecord):
activerecord:
attributes:
article:
cost: "Total cost" label(:cost)
# => <label for="article_cost">Total cost</label>
label(:title, "A short title")
# => <label for="article_title">A short title</label>
label(:title, "A short title", class: "title_label")
# => <label for="article_title" class="title_label">A short title</label>
label(:privacy, "Public Article", value: "public")
# => <label for="article_privacy_public">Public Article</label>
label(:cost) do |translation|
content_tag(:span, translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
label(: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(:cost) do |builder|
content_tag(:span, builder.translation, class: [
"cost_label",
("error_label" if builder.object.errors.include?(:cost))
])
end
# => <label for="article_cost"><span class="cost_label error_label">Total cost</span></label>
label(: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 1947
Оборачивает ActionView::Helpers::FormHelper#month_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.month_field :birthday_month %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1700
def multipart=(multipart)
@multipart = multipart
if parent_builder = @options[:parent_builder]
parent_builder.multipart = multipart
end
end # File actionview/lib/action_view/helpers/form_helper.rb, line 1999
Оборачивает ActionView::Helpers::FormHelper#number_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.number_field :age %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1817
Оборачивает ActionView::Helpers::FormHelper#password_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.password_field :password %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1882
Оборачивает ActionView::Helpers::FormHelper#phone_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.phone_field :phone %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 2496
def radio_button(method, tag_value, options = {})
@template.radio_button(@object_name, method, tag_value, objectify_options(options))
end Возвращает тег радиокнопки для доступа к указанному атрибуту (определяемому method) объекта, присвоенного шаблону (определяемому object). Если текущее значение method равно tag_value, радиокнопка будет отмечена.
Чтобы принудительно установить радиокнопку в отмеченное состояние, передайте checked: true в хэш options. Вы также можете передать там параметры HTML.
# Let's say that @article.category returns "rails":
radio_button("category", "rails")
radio_button("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("receive_newsletter", "yes")
radio_button("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 2012
Оборачивает ActionView::Helpers::FormHelper#range_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.range_field :age %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actiontext/app/helpers/action_text/tag_helper.rb, line 101
def rich_textarea(method, options = {})
@template.rich_textarea(@object_name, method, objectify_options(options))
end Оборачивает ActionView::Helpers::FormHelper#rich_textarea для билдеров форм:
<%= form_with model: @message do |f| %> <%= f.rich_textarea :content %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1856
Оборачивает ActionView::Helpers::FormHelper#search_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.search_field :name %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 849
def select(method, choices = nil, options = {}, html_options = {}, &block)
@template.select(@object_name, method, choices, objectify_options(options), @default_html_options.merge(html_options), &block)
end Оборачивает ActionView::Helpers::FormOptionsHelper#select для билдеров форм:
<%= form_with model: @post do |f| %>
<%= f.select :person_id, Person.all.collect { |p| [ p.name, p.id ] }, include_blank: true %>
<%= f.submit %>
<% end %> Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 2589
def submit(value = nil, options = {})
value, options = nil, value if value.is_a?(Hash)
value ||= submit_default_value
@template.submit_tag(value, options)
end Добавляет кнопку отправки для заданной формы. При отсутствии значения проверяется, является ли объект новым ресурсом, чтобы создать соответствующую метку:
<%= form_with model: @article do |f| %> <%= f.submit %> <% end %>
В примере выше, если @article является новой записью, будет использоваться «Создать статью» в качестве метки кнопки отправки; в противном случае используется «Обновить статью».
Эти метки можно настроить с помощью I18n по ключу helpers.submit и используя %{model} для интерполяции перевода:
en:
helpers:
submit:
create: "Create a %{model}"
update: "Confirm changes to %{model}" Также ищется ключ, специфичный для данного объекта:
en:
helpers:
submit:
article:
create: "Add %{model}" # File actionview/lib/action_view/helpers/form_helper.rb, line 1869
Оборачивает ActionView::Helpers::FormHelper#telephone_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.telephone_field :phone %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1804
Оборачивает ActionView::Helpers::FormHelper#text_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.text_field :name %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1830
Оборачивает ActionView::Helpers::FormHelper#textarea для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.textarea :detail %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1908
Оборачивает ActionView::Helpers::FormHelper#time_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.time_field :born_at %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/date_helper.rb, line 1249
def time_select(method, options = {}, html_options = {})
@template.time_select(@object_name, method, objectify_options(options), html_options)
end Оборачивает ActionView::Helpers::DateHelper#time_select для билдеров форм:
<%= form_with model: @race do |f| %> <%= f.time_select :average_lap %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 885
def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
@template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_html_options.merge(html_options))
end Оборачивает ActionView::Helpers::FormOptionsHelper#time_zone_select для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.time_zone_select :time_zone, nil, include_blank: true %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1716 def to_model self end
# File actionview/lib/action_view/helpers/form_helper.rb, line 1712 def to_partial_path self.class._to_partial_path end
# File actionview/lib/action_view/helpers/form_helper.rb, line 1973
Оборачивает ActionView::Helpers::FormHelper#url_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.url_field :homepage %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1960
Оборачивает ActionView::Helpers::FormHelper#week_field для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.week_field :birthday_week %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 897
def weekday_select(method, options = {}, html_options = {})
@template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
end Оборачивает ActionView::Helpers::FormOptionsHelper#weekday_select для билдеров форм:
<%= form_with model: @user do |f| %> <%= f.weekday_select :weekday, include_blank: true %> <%= f.submit %> <% end %>
Для получения подробностей обратитесь к документации базового помощника.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.