Spec-Zone.ru › Ruby on Rails 8.0

модуль 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 - может быть одиночным значением или массивом значений, которые будут отключенными элементами в итоговом выводе.

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

    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(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 782
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 и в нашем действии обновления есть следующий код:

@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 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

Технические нюансы

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

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

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

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

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

Не выберет человека с id 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 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

Особенности

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