Spec-Zone.ru › Ruby on Rails 5.0

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

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

Предоставляет множество методов для преобразования различных типов контейнеров в набор тегов 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=""></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=""></option>
      <option value="joke">joke</option>
      <option value="poem">poem</option>
      <option disabled="disabled" value="restricted">restricted</option>
    </select>

    Когда используется вспомогательный метод collection_select, :disabled также может быть методом Proc, который определяет те 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) Показать исходный код
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 750
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

Примечания

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

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

@user.update(params[:user])

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

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

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

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 666
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 не отправляется. Поэтому, любой idiom сильных параметров, такой как

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

вызовет ошибку, поскольку {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 201
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 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, выбор не производится, если не включены :prompt или :include_blank в хэше options.

Параметры:

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

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

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

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

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

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

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

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

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

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

class City < ActiveRecord::Base
  belongs_to :country
  # attribs: id, name, country_id
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 525
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".freeze, 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".freeze, 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"]]]
  • 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 455
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(
      group.send(group_method), option_key_method, option_value_method, selected_key)

    content_tag("optgroup".freeze, option_tags, label: group.send(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 351
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

    content_tag_string(:option, text, html_attributes)
  end.join("\n").html_safe
end

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

Например:

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=""></option>
  <option value="1" selected="selected">David</option>
  <option value="2">Eileen</option>
  <option value="3">Rafael</option>
</select>

при условии, что соответствующий человек имеет ID 1.

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

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

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

select(report, "campaign_ids") do
  available_campaigns.each do |c|
    content_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 не отправляется. Таким образом, любой idiom массового назначения, как

@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 569
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 =~ priority_zones }
    end

    zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
    zone_options.safe_concat content_tag("option".freeze, '-------------', 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 для удобства получения списка часовых поясов США или регулярное выражение для выбора необходимых поясов)

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

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

ПРИМЕЧАНИЕ: Возвращаются только теги 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 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 и 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 для часовых поясов другой страны или регулярное выражение для выбора необходимых поясов.

Наконец, этот метод поддерживает параметр :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)

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

Spec-Zone.ru

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