Трудно ответить точно, не зная, как выглядят данные, но я собираюсь догадаться, что у вас есть что-то вроде этого:
@grouped_options = [
["Some nil value label"],
["Option one", "1"],
["Option Group 1",
[
["Option one in group 1", "1:1"],
["Option two in group 1", "1:2"],
]
],
["Option Group 2",
[
["Option one in group 2", "2:1"],
["Option two in group 2", "2:2"],
]
],
]
С этим у вас есть пара вариантов. В простом ERB вы можете сделать это так:
<%= select "thing", "some_attr" do %>
<% @grouped_options.each do |label, value_or_options| %>
<% if Array === value_or_options %>
<%= tag.optgroup options_for_select(value_or_options), label: label %>
<% else %>
<%= tag.option label, value: value_or_options %>
<% end %>
<% end %>
<% end %>
Лично я бы написал помощника. Метод Enumerable#chunk
разбивает массив на серии значений, которые возвращают одно и то же для данного блока, упрощая разделение сгруппированных и не сгруппированных элементов, поэтому мы можем использовать grouped_options_for_select
и options_for_select
соответственно:
def ungrouped_and_grouped_options_for_select(choices, selected_key = nil)
capture do
choices
.chunk {|_, choice_or_group| Array === choice_or_group }
.each do |is_group, choices_or_grouped_choices|
if is_group
concat grouped_options_for_select(choices_or_grouped_choices, selected_key)
else
concat options_for_select(choices_or_grouped_choices, selected_key)
end
end
end
end
Вы можете использовать это так:
<%= select "thing", "some_attr" do %>
<%= ungrouped_and_grouped_options_for_select(@grouped_options) %>
<% end %>
Вы можете увидеть оба этих подхода в действии на repl.it: https://repl.it/@jrunning/UnacceptablePlaintiveServer (см. views/tests/index.html.erb
, controllers/tests_controller.rb
и helpers/application_helper.rb
).