Spec-Zone.ru › Ruby on Rails 7.1

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

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

Справочник по вспомогательным функциям Action View для выбора параметров формы

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

Методы collection_select, select и time_zone_select принимают параметр options, представляющий собой хэш:

  • :include_blank — устанавливается в значение true или строку-подсказку, если первый элемент option в элементе 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 ещё не имеет значения, этот параметр добавляет option с общим запросом — «Пожалуйста, выберите» — или заданной строкой-подсказкой.

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

    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 также может быть процедурой, которая определяет опции, которые должны быть отключены.

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

    Если категории «2008 stuff» и «Christmas» возвращают true при вызове метода archived?, это вернёт:

    <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(объект, метод, коллекция, метод_значения, метод_текста, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 782
def collection_check_boxes(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_check_boxes(: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_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
  b.label { b.check_box }
end

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

Методы билдера label и check_box также принимают дополнительные HTML-параметры:

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

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

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

Gotcha

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

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

@user.update(params[:user])

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

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

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

collection_radio_buttons(объект, метод, коллекция, метод_значения, метод_текста, options = {}, html_options = {}, &block) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 698
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

Gotcha

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

params.require(:user).permit(...)

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

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

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

collection_select(объект, метод, коллекция, метод_значения, метод_текста, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 199
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, выбор не делается, если не включить :prompt или :include_blank в хеш options.

Параметры :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(объект, метод, коллекция, метод_группы, метод_метки_группы, метод_ключа_варианта, метод_значения_варианта, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 258
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, выбор не делается, если не включить :prompt или :include_blank в хеш options.

Параметры:

  • 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 534
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 462
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 358
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.content_tag_string(:option, text, html_attributes)
  end.join("\n").html_safe
end

Принимает контейнер (хеш, массив, перечисляемый объект) и возвращает строку тегов option. Если элементы контейнера поддерживают методы first и last (например, массив из двух элементов), «last» используется как значение опции, а «first» - как текстовое значение. Хеши автоматически преобразуются в этот формат, поэтому ключи становятся «first», а значения - «last». Если selected указано, соответствующий «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>

ПРИМЕЧАНИЕ: Возвращаются только теги 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 401
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

Возвращает строку тегов option, сгенерированных итерацией по 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')

Не выберет человека с id 1, потому что 1 (целое число) не равно '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 159
def select(object, method, choices = nil, options = {}, html_options = {}, &block)
  Tags::Select.new(object, method, self, choices, options, html_options, &block).render
end

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

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

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

Блок может быть передан в select для настройки рендеринга тегов option. Это полезно, когда тег option имеет сложные атрибуты.

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

Gotcha

Спецификация 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 579
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

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

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

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

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

time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 292
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> и <option> для данного объекта и метода, используя time_zone_options_for_select для генерации списка тегов <option>.

В дополнение к параметру :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 611
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

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

Параметры:

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

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

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

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

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

Spec-Zone.ru

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