Spec-Zone.ru › Ruby on Rails 8.1

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

Включённые модули:
ActionView::Helpers::TextHelper

Помощники параметров форм Action View

Предоставляет ряд методов для преобразования различных типов контейнеров в набор тегов параметров.

Методы collection_select, select и time_zone_select принимают параметр options — хеш:

  • :include_blank — задайте значение true или строку-подсказку, если первый элемент параметра select должен быть пустым. Полезно, если для элемента select не требуется значение по умолчанию.

    select(:post, :category, Post::CATEGORIES, { include_blank: true })
    

    может превратиться в:

    <select name="post[category]" id="post_category">
      <option value="" label=" "></option>
      <option value="joke">joke</option>
      <option value="poem">poem</option>
    </select>

    Ещё один распространённый случай — тег select для объекта, связанного через belongs_to.

    Пример с @post.person_id => 2:

    select(:post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: "None" })
    

    может превратиться в:

    <select name="post[person_id]" id="post_person_id">
      <option value="">None</option>
      <option value="1">David</option>
      <option value="2" selected="selected">Eileen</option>
      <option value="3">Rafael</option>
    </select>
  • :prompt — задайте значение true или строку-подсказку. Если у элемента select ещё нет значения, перед ним добавляется параметр с общей подсказкой — «Выберите» — или указанной строкой-подсказкой.

    select(:post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { prompt: "Select Person" })
    

    может превратиться в:

    <select name="post[person_id]" id="post_person_id">
      <option value="">Select Person</option>
      <option value="1">David</option>
      <option value="2">Eileen</option>
      <option value="3">Rafael</option>
    </select>
  • :index — как и другие помощники форм, select принимает параметр :index, позволяющий вручную задать идентификатор, используемый в результирующем выводе. В отличие от других помощников, select ожидает этот параметр в параметре html_options.

    select("album[]", :genre, %w[ rap rock country ], {}, { index: nil })
    

    превращается в:

    <select name="album[][genre]" id="album__genre">
      <option value="rap">rap</option>
      <option value="rock">rock</option>
      <option value="country">country</option>
    </select>
  • :disabled — может быть отдельным значением или массивом значений, соответствующих отключённым параметрам в итоговом выводе.

    select(:post, :category, Post::CATEGORIES, { disabled: "restricted" })
    

    может превратиться в:

    <select name="post[category]" id="post_category">
      <option value="joke">joke</option>
      <option value="poem">poem</option>
      <option disabled="disabled" value="restricted">restricted</option>
    </select>

    При использовании с помощником collection_select :disabled также может быть Proc, определяющим параметры, которые следует отключить.

    collection_select(:post, :category_id, Category.all, :id, :name, { disabled: -> (category) { category.archived? } })
    

    Если для категорий «материалы 2008 года» и «Рождество» метод archived? возвращает true, результат будет таким:

    <select name="post[category_id]" id="post_category_id">
      <option value="1" disabled="disabled">2008 stuff</option>
      <option value="2" disabled="disabled">Christmas</option>
      <option value="3">Jokes</option>
      <option value="4">Poems</option>
    </select>

Открытые методы экземпляра

collection_check_boxes (object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
Псевдоним для: collection_checkboxes
collection_checkboxes (object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 784
def collection_checkboxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
end

Возвращает теги флажков для коллекции существующих возвращаемых значений method класса object. Будет выбран результат вызова method для экземпляра object. Если вызов method возвращает nil, выбор не производится.

Параметры :value_method и :text_method — это методы, вызываемые для каждого элемента collection. Их возвращаемые значения используются соответственно в качестве атрибута value и содержимого каждого тега флажка. Также это может быть любой объект, отвечающий на call, например proc, который будет вызван для каждого элемента collection, чтобы получить значение/текст.

Пример структуры объекта для использования с этим методом:

class Post < ActiveRecord::Base
  has_and_belongs_to_many :authors
end
class Author < ActiveRecord::Base
  has_and_belongs_to_many :posts
  def name_with_initial
    "#{first_name.first}. #{last_name}"
  end
end

Пример использования (выбор связанного автора для экземпляра Post, @post):

collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial)

Если @post.author_ids уже имеет значение [1], результат будет таким:

<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
<label for="post_author_ids_3">M. Clark</label>
<input name="post[author_ids][]" type="hidden" value="" />

Также можно настроить отображение элементов, передав методу блок:

collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
  b.label { b.checkbox }
end

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

Методы построителя label и checkbox также принимают дополнительные параметры HTML:

collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
  b.label(class: "checkbox") { b.checkbox(class: "checkbox") }
end

Также доступны три специальных метода: object, text и value, которые соответственно возвращают текущий отображаемый элемент, его текст и значение. Их можно использовать так:

collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
   b.label(:"data-value" => b.value) { b.checkbox + b.text }
end

Особый случай

Если для коллекции флажков ничего не выбрано, большинство веб-браузеров не отправляют никакого значения.

Например, если у нас есть модель User с полем category_ids и в действии update используется следующий код:

@user.update(params[:user])

Если не выбрано ни одного category_ids, можно смело предположить, что это поле не будет обновлено.

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

В редких случаях, когда это скрытое поле не нужно, можно передать вспомогательному методу параметр include_hidden: false.

Также имеет псевдоним: collection_check_boxes
collection_radio_buttons (object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 700
def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  Tags::CollectionRadioButtons.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
end

Возвращает теги переключателей для коллекции существующих возвращаемых значений method класса object. Будет выбран результат вызова method для экземпляра object. Если вызов method возвращает nil, выбор не производится.

Параметры :value_method и :text_method — это методы, вызываемые для каждого элемента collection. Их возвращаемые значения используются соответственно в качестве атрибута value и содержимого каждого тега переключателя. Также это может быть любой объект, отвечающий на call, например proc, который будет вызван для каждого элемента collection, чтобы получить значение/текст.

Пример структуры объекта для использования с этим методом:

class Post < ActiveRecord::Base
  belongs_to :author
end

class Author < ActiveRecord::Base
  has_many :posts

  def name_with_initial
    "#{first_name.first}. #{last_name}"
  end
end

Пример использования (выбор связанного автора для экземпляра Post, @post):

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial)

Если @post.author_id уже имеет значение 1, результат будет таким:

<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" checked="checked" />
<label for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label for="post_author_id_2">D. Thomas</label>
<input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
<label for="post_author_id_3">M. Clark</label>

Также можно настроить отображение элементов, передав методу блок:

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
  b.label { b.radio_button }
end

Аргумент, передаваемый блоку, — это специальный тип построителя для этой коллекции, который умеет создавать метку и переключатель для текущего элемента коллекции с соответствующими текстом и значением. С его помощью можно изменить порядок отображения метки и переключателя или даже использовать метку в качестве обёртки, как в примере выше.

Методы построителя label и radio_button также принимают дополнительные параметры HTML:

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
  b.label(class: "radio_button") { b.radio_button(class: "radio_button") }
end

Также доступны три специальных метода: object, text и value, которые соответственно возвращают текущий отображаемый элемент, его текст и значение. Их можно использовать так:

collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
   b.label(:"data-value" => b.value) { b.radio_button + b.text }
end

Особый случай

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

params.expect(user: [...])

вызовет ошибку, поскольку {user: ...} не будет задан.

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

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

collection_select (object, method, collection, value_method, text_method, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 198
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
  Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render
end

Возвращает теги <select> и <option> для коллекции существующих возвращаемых значений method класса object. Будет выбран результат вызова method для экземпляра object. Если вызов method возвращает nil, выбор не производится, если в хэш options не включить :prompt или :include_blank.

Параметры :value_method и :text_method — это методы, вызываемые для каждого элемента collection. Их возвращаемые значения используются соответственно в качестве атрибута value и содержимого каждого тега <option>. Также это может быть любой объект, отвечающий на call, например proc, который будет вызван для каждого элемента collection, чтобы получить значение/текст.

Пример структуры объекта для использования с этим методом:

class Post < ActiveRecord::Base
  belongs_to :author
end

class Author < ActiveRecord::Base
  has_many :posts

  def name_with_initial
    "#{first_name.first}. #{last_name}"
  end
end

Пример использования (выбор связанного автора для экземпляра Post, @post):

collection_select(:post, :author_id, Author.all, :id, :name_with_initial, prompt: true)

Если @post.author_id уже имеет значение 1, результат будет таким:

<select name="post[author_id]" id="post_author_id">
  <option value="">Please select</option>
  <option value="1" selected="selected">D. Heinemeier Hansson</option>
  <option value="2">D. Thomas</option>
  <option value="3">M. Clark</option>
</select>
grouped_collection_select (object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 257
def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
  Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render
end

Возвращает теги <select>, <optgroup> и <option> для коллекции существующих возвращаемых значений method класса object. Будет выбран результат вызова method для экземпляра object. Если вызов method возвращает nil, выбор не производится, если в хэш options не включить :prompt или :include_blank.

Параметры:

  • object — экземпляр класса, используемый для тега select

  • method — атрибут object, соответствующий тегу select

  • collection — массив объектов, представляющих теги <optgroup>.

  • group_method — имя метода, который при вызове для элемента collection возвращает массив дочерних объектов, представляющих теги <option>. Также это может быть любой объект, отвечающий на call, например proc, который будет вызван для каждого элемента collection, чтобы получить значение.

  • group_label_method — имя метода, который при вызове для элемента collection возвращает строку, используемую в качестве атрибута label для его тега <optgroup>. Также это может быть любой объект, отвечающий на call, например proc, который будет вызван для каждого элемента collection, чтобы получить метку.

  • option_key_method — имя метода, который при вызове для дочернего объекта элемента collection возвращает значение, используемое в качестве атрибута value для его тега <option>.

  • option_value_method — имя метода, который при вызове для дочернего объекта элемента collection возвращает значение, используемое в качестве содержимого его тега <option>.

Пример структуры объекта для использования с этим методом:

# attributes: id, name
class Continent < ActiveRecord::Base
  has_many :countries
end

# attributes: id, name, continent_id
class Country < ActiveRecord::Base
  belongs_to :continent
end

# attributes: id, name, country_id
class City < ActiveRecord::Base
  belongs_to :country
end

Пример использования:

grouped_collection_select(:city, :country_id, @continents, :countries, :name, :id, :name)

Возможный результат:

<select name="city[country_id]" id="city_country_id">
  <optgroup label="Africa">
    <option value="1">South Africa</option>
    <option value="3">Somalia</option>
  </optgroup>
  <optgroup label="Europe">
    <option value="7" selected="selected">Denmark</option>
    <option value="2">Ireland</option>
  </optgroup>
</select>
grouped_options_for_select (grouped_options, selected_key = nil, options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 535
def grouped_options_for_select(grouped_options, selected_key = nil, options = {})
  prompt  = options[:prompt]
  divider = options[:divider]

  body = "".html_safe

  if prompt
    body.safe_concat content_tag("option", prompt_text(prompt), value: "")
  end

  grouped_options.each do |container|
    html_attributes = option_html_attributes(container)

    if divider
      label = divider
    else
      label, container = container
    end

    html_attributes = { label: label }.merge!(html_attributes)
    body.safe_concat content_tag("optgroup", options_for_select(container, selected_key), html_attributes)
  end

  body
end

Возвращает строку с тегами <option>, как options_for_select, но оборачивает их в теги <optgroup>:

grouped_options = [
 ['North America',
   [['United States','US'],'Canada']],
 ['Europe',
   ['Denmark','Germany','France']]
]
grouped_options_for_select(grouped_options)

grouped_options = {
  'North America' => [['United States','US'], 'Canada'],
  'Europe' => ['Denmark','Germany','France']
}
grouped_options_for_select(grouped_options)

Возможный результат:

<optgroup label="North America">
  <option value="US">United States</option>
  <option value="Canada">Canada</option>
</optgroup>
<optgroup label="Europe">
  <option value="Denmark">Denmark</option>
  <option value="Germany">Germany</option>
  <option value="France">France</option>
</optgroup>

Параметры

  • grouped_options — принимает вложенный массив или хэш строк. Первое значение служит меткой <optgroup>, а второе должно быть массивом вариантов. Второе значение может быть вложенным массивом пар текст-значение. Подробнее см. в разделе options_for_select.

    Ex. ["North America",[["United States","US"],["Canada","CA"]]]

    В качестве необязательного третьего значения можно передать атрибуты HTML для optgroup.

    Ex. ["North America",[["United States","US"],["Canada","CA"]], { disabled: "disabled" }]
  • selected_key — значение, совпадающее с атрибутом value одного из тегов <option>; для этого тега будет установлен атрибут selected. Примечание: это значение может совпадать с несколькими вариантами, если один и тот же вариант присутствует в нескольких группах. Тогда атрибут selected="selected" будет установлен для каждого из них.

Параметры

  • :prompt — установите значение true или строку-подсказку. Если у элемента select ещё нет значения, перед вариантами добавляется вариант с общей подсказкой «Выберите» или с указанной строкой-подсказкой.

  • :divider — разделитель групп вариантов.

    grouped_options = [
      [['United States','US'], 'Canada'],
      ['Denmark','Germany','France']
    ]
    grouped_options_for_select(grouped_options, nil, divider: '---------')
    

    Возможный результат:

    <optgroup label="---------">
      <option value="US">United States</option>
      <option value="Canada">Canada</option>
    </optgroup>
    <optgroup label="---------">
      <option value="Denmark">Denmark</option>
      <option value="Germany">Germany</option>
      <option value="France">France</option>
    </optgroup>

Примечание: Возвращаются только теги <optgroup> и <option>, поэтому результат необходимо обернуть в соответствующий тег <select>.

option_groups_from_collection_for_select (collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 461
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
  collection.map do |group|
    option_tags = options_from_collection_for_select(
      value_for_collection(group, group_method), option_key_method, option_value_method, selected_key)

    content_tag("optgroup", option_tags, label: value_for_collection(group, group_label_method))
  end.join.html_safe
end

Возвращает строку с тегами <option>, как options_from_collection_for_select, но группирует их с помощью тегов <optgroup> на основе взаимосвязей между объектами, заданных аргументами.

Параметры:

  • collection — массив объектов, представляющих теги <optgroup>.

  • group_method — имя метода, который при вызове для элемента collection возвращает массив дочерних объектов, представляющих теги <option>.

  • group_label_method — имя метода, который при вызове для элемента collection возвращает строку, используемую в качестве атрибута label для его тега <optgroup>.

  • option_key_method — имя метода, который при вызове для дочернего объекта элемента collection возвращает значение, используемое в качестве атрибута value для его тега <option>.

  • option_value_method — имя метода, который при вызове для дочернего объекта элемента collection возвращает значение, используемое в качестве содержимого его тега <option>.

  • selected_key — значение, совпадающее с атрибутом value одного из тегов <option>; для этого тега будет установлен атрибут selected. Соответствует возвращаемому значению одного из вызовов option_key_method. Если задано nil, выбор не производится. Также может быть хэшем, если нужно указать отключённые значения.

Пример структуры объекта для использования с этим методом:

class Continent < ActiveRecord::Base
  has_many :countries
  # attribs: id, name
end

class Country < ActiveRecord::Base
  belongs_to :continent
  # attribs: id, name, continent_id
end

Пример использования:

option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)

Возможный результат:

<optgroup label="Africa">
  <option value="1">Egypt</option>
  <option value="4">Rwanda</option>
  ...
</optgroup>
<optgroup label="Asia">
  <option value="3" selected="selected">China</option>
  <option value="12">India</option>
  <option value="5">Japan</option>
  ...
</optgroup>

Примечание: Возвращаются только теги <optgroup> и <option>, поэтому результат необходимо обернуть в соответствующий тег <select>.

options_for_select (container, selected = nil) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 357
def options_for_select(container, selected = nil)
  return container if String === container

  selected, disabled = extract_selected_and_disabled(selected).map do |r|
    Array(r).map(&:to_s)
  end

  container.map do |element|
    html_attributes = option_html_attributes(element)
    text, value = option_text_and_value(element).map(&:to_s)

    html_attributes[:selected] ||= option_value_selected?(value, selected)
    html_attributes[:disabled] ||= disabled && option_value_selected?(value, disabled)
    html_attributes[:value] = value

    tag_builder.option(text, **html_attributes)
  end.join("\n").html_safe
end

Принимает контейнер (хэш, массив, перечислимый объект или объект вашего типа) и возвращает строку с тегами вариантов. Если элементы контейнера отвечают на first и last (например, это двухэлементный массив), «последние» значения используются как значения вариантов, а «первые» — как текст вариантов. Хэши автоматически преобразуются в такой формат: ключи становятся «первыми» значениями, а значения — последними. Если задан параметр selected, соответствующий «последний» элемент или значение получит тег выбранного варианта. selected также может быть массивом значений, которые нужно выбрать при использовании множественного выбора.

options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
# => <option value="$">Dollar</option>
# => <option value="DKK">Kroner</option>

options_for_select([ "VISA", "MasterCard" ], "MasterCard")
# => <option value="VISA">VISA</option>
# => <option selected="selected" value="MasterCard">MasterCard</option>

options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
# => <option value="$20">Basic</option>
# => <option value="$40" selected="selected">Plus</option>

options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
# => <option selected="selected" value="VISA">VISA</option>
# => <option value="MasterCard">MasterCard</option>
# => <option selected="selected" value="Discover">Discover</option>

В качестве последнего элемента массива можно указать атрибуты HTML.

options_for_select([ "Denmark", ["USA", { class: 'bold' }], "Sweden" ], ["USA", "Sweden"])
# => <option value="Denmark">Denmark</option>
# => <option value="USA" class="bold" selected="selected">USA</option>
# => <option value="Sweden" selected="selected">Sweden</option>

options_for_select([["Dollar", "$", { class: "bold" }], ["Kroner", "DKK", { onclick: "alert('HI');" }]])
# => <option value="$" class="bold">Dollar</option>
# => <option value="DKK" onclick="alert('HI');">Kroner</option>

Чтобы указать отключённые варианты, задайте selected в виде хэша, где :disabled — значение или массив значений, которые нужно отключить. В этом случае для указания выбранных тегов вариантов можно использовать :selected.

options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: "Super Platinum")
# => <option value="Free">Free</option>
# => <option value="Basic">Basic</option>
# => <option value="Advanced">Advanced</option>
# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>

options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: ["Advanced", "Super Platinum"])
# => <option value="Free">Free</option>
# => <option value="Basic">Basic</option>
# => <option value="Advanced" disabled="disabled">Advanced</option>
# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>

options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], selected: "Free", disabled: "Super Platinum")
# => <option value="Free" selected="selected">Free</option>
# => <option value="Basic">Basic</option>
# => <option value="Advanced">Advanced</option>
# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>

ПРИМЕЧАНИЕ: Возвращаются только теги вариантов; этот вызов необходимо обернуть в обычный тег HTML select.

options_from_collection_for_select (collection, value_method, text_method, selected = nil) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 400
def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
  options = collection.map do |element|
    [value_for_collection(element, text_method), value_for_collection(element, value_method), option_html_attributes(element)]
  end
  selected, disabled = extract_selected_and_disabled(selected)
  select_deselect = {
    selected: extract_values_from_collection(collection, value_method, selected),
    disabled: extract_values_from_collection(collection, value_method, disabled)
  }

  options_for_select(options, select_deselect)
end

Возвращает строку с тегами вариантов, созданными путём перебора collection и присвоения результату вызова value_method значения варианта, а text_method — его текста.

options_from_collection_for_select(@people, 'id', 'name')
# => <option value="#{person.id}">#{person.name}</option>

Чаще всего этот метод используется внутри select_tag, как в следующем примере:

select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')

Если selected задано как значение или массив значений, элементам, для которых value_method возвращает совпадение, будут соответствовать выбранные теги вариантов.

Если selected задан как Proc, выбранными значениями будут элементы коллекции, для которых анонимная функция возвращает true.

selected также может быть хэшем, задающим значения :selected и/или :disabled.

При указании выбранных или отключённых вариантов обязательно используйте тот же класс, что и у value_method. Иначе результат будет неверным. Пример:

options_from_collection_for_select(@people, 'id', 'name', '1')

не выберет человека с идентификатором 1, потому что 1 (Integer) — это не то же самое, что «1» (строка)

options_from_collection_for_select(@people, 'id', 'name', 1)

должен дать ожидаемый результат.

select (object, method, choices = nil, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 158
def select(object, method, choices = nil, options = {}, html_options = {}, &block)
  Tags::Select.new(object, method, self, choices, options, html_options, &block).render
end

Создаёт тег select и содержащуюся в нём последовательность тегов вариантов для заданных объекта и метода. Если объект доступен, будет выбран текущий вариант, хранящийся в нём.

Параметр choices допускает два формата, соответствующих результатам других вспомогательных методов:

  • Плоская коллекция (см. options_for_select).

  • Вложенная коллекция (см. grouped_options_for_select).

Пример с @post.person_id => 2:

select :post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true }

превратится в:

<select name="post[person_id]" id="post_person_id">
  <option value="" label=" "></option>
  <option value="1">David</option>
  <option value="2" selected="selected">Eileen</option>
  <option value="3">Rafael</option>
</select>

Это можно использовать, чтобы стандартным способом предоставить набор вариантов по умолчанию: перед отображением формы создания новому экземпляру модели назначаются варианты по умолчанию, и он привязывается к @model_name. Обычно эта модель не сохраняется в базе данных. Вместо этого при получении запроса на создание создаётся второй объект модели. Это позволяет пользователю отправить страницу формы несколько раз и получить ожидаемый результат — создать несколько записей. Кроме того, так можно использовать один partial для создания полей формы как редактирования, так и создания.

По умолчанию выбран вариант post.person_id. Укажите selected: value, чтобы выбрать другой вариант, или selected: nil, чтобы оставить все варианты невыбранными. Аналогично, можно указать отключаемые варианты в тегах вариантов с помощью параметра :disabled. Это может быть одно значение или массив значений, которые нужно отключить.

В select можно передать блок, чтобы настроить отображение тегов вариантов. Это удобно, если тег варианта имеет сложные атрибуты.

select(report, :campaign_ids) do
  available_campaigns.each do |c|
    tag.option(c.name, value: c.id, data: { tags: c.tags.to_json })
  end
end

Особый случай

Согласно спецификации HTML, если параметру multiple передано значение select и все варианты сняты, веб-браузеры не отправляют на сервер никакого значения. К сожалению, это создаёт проблему: если у модели User есть несколько roles и аксессор role_ids, а в форме редактирования ролей пользователь снимает все роли в поле множественного выбора role_ids, параметр role_ids не отправляется. Поэтому любой идиоматический код массового присваивания вроде

@user.update(params[:user])

не обновит роли.

Чтобы этого избежать, вспомогательный метод создаёт вспомогательное скрытое поле перед каждым элементом множественного выбора. У скрытого поля такое же имя, как у поля множественного выбора, а его значение пустое.

Примечание: Клиент отправляет либо только скрытое поле (представляющее поле множественного выбора без выбранных вариантов), либо оба поля. Это означает, что результирующий массив всегда содержит пустую строку.

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

time_zone_options_for_select (selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 580
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
  zone_options = "".html_safe

  zones = model.all
  convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }

  if priority_zones
    if priority_zones.is_a?(Regexp)
      priority_zones = zones.select { |z| z.match?(priority_zones) }
    end

    zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
    zone_options.safe_concat content_tag("option", "-------------", value: "", disabled: true)
    zone_options.safe_concat "\n"

    zones = zones - priority_zones
  end

  zone_options.safe_concat options_for_select(convert_zones[zones], selected)
end

Возвращает строку с тегами вариантов для практически любого часового пояса в мире. Передайте имя ActiveSupport::TimeZone в качестве selected, чтобы пометить его тег варианта как выбранный. Также можно передать массив объектов ActiveSupport::TimeZone в качестве priority_zones, чтобы они отображались перед остальными элементами длинного списка. (Для удобства получения списка часовых поясов США можно использовать ActiveSupport::TimeZone.us_zones, а для выбора нужных поясов — Regexp.)

Параметр selected должен иметь значение nil или быть строкой, задающей имя ActiveSupport::TimeZone.

По умолчанию model — это константа ActiveSupport::TimeZone (в Active Record её можно получить как объект-значение). Параметр model должен отвечать на all и возвращать массив объектов, представляющих часовые пояса; каждый объект должен отвечать на name. Если передано Regexp, для сопоставления часовых поясов будет использоваться метод match?.

ПРИМЕЧАНИЕ: Возвращаются только теги вариантов; этот вызов необходимо обернуть в обычный тег HTML select.

time_zone_select (object, method, priority_zones = nil, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 291
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
  Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render
end

Возвращает теги select и вариантов для заданных объекта и метода, используя time_zone_options_for_select для создания списка тегов вариантов.

Помимо описанного выше параметра :include_blank, этот метод также поддерживает параметр :model, по умолчанию равный ActiveSupport::TimeZone. С его помощью можно указать другой объект модели часового пояса. (Подробнее см. в разделе time_zone_options_for_select.)

Также можно передать массив объектов ActiveSupport::TimeZone в качестве priority_zones, чтобы они отображались перед остальными элементами длинного списка. Для получения списка часовых поясов США можно использовать ActiveSupport::TimeZone.us_zones, часовых поясов другой страны — ActiveSupport::TimeZone.country_zones(country_code), а для выбора нужных поясов — Regexp.

Наконец, этот метод поддерживает параметр :default, который выбирает часовой пояс ActiveSupport::TimeZone по умолчанию, если часовой пояс объекта равен nil.

time_zone_select(:user, :time_zone, nil, include_blank: true)

time_zone_select(:user, :time_zone, nil, default: "Pacific Time (US & Canada)")

time_zone_select(:user, :time_zone, ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")

time_zone_select(:user, :time_zone, [ ActiveSupport::TimeZone["Alaska"], ActiveSupport::TimeZone["Hawaii"] ])

time_zone_select(:user, :time_zone, /Australia/)

time_zone_select(:user, :time_zone, ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)
weekday_options_for_select (selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 613
def weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week)
  day_names = I18n.translate("date.#{day_format}")
  day_names = day_names.map.with_index.to_a if index_as_value
  day_names = day_names.rotate(Date::DAYS_INTO_WEEK.fetch(beginning_of_week))

  options_for_select(day_names, selected)
end

Возвращает строку с тегами вариантов для дней недели.

Параметры

  • :index_as_value — по умолчанию false; задайте true, чтобы использовать индексы из I18n.translate("date.day_names") в качестве значений. По умолчанию воскресенье всегда имеет значение 0.

  • :day_format — ключ I18n массива, используемого для вариантов дней недели. По умолчанию :day_names; задайте :abbr_day_names, чтобы использовать сокращения.

  • :beginning_of_week — по умолчанию Date.beginning_of_week.

ПРИМЕЧАНИЕ: Возвращаются только теги вариантов; этот вызов необходимо обернуть в обычный тег HTML select.

weekday_select (object, method, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 297
def weekday_select(object, method, options = {}, html_options = {}, &block)
  Tags::WeekdaySelect.new(object, method, self, options, html_options, &block).render
end

Возвращает теги select и вариантов для заданных объекта и метода, используя weekday_options_for_select для создания списка тегов вариантов.

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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