我有一个Location
模型,其name
和area
属性。我想创建一个选择输入字段,我的选项被分组,如下所示:
<optgroup label="Area1">
<option value=1>Location 1</option>
<option value=2>Location 2</option>
<option value=3>Location 3</option>
</optgroup>
<optgroup label="Area2">
<option value=4>Location 4</option>
<option value=5>Location 5</option>
<option value=6>Location 6</option>
</optgroup>
我在控制器中尝试了以下操作并查看:
控制器:
@grouped_locations = Location.pluck(:area, :name).group_by(&:first).
map { |k, v_ary| [k, v_ary.map(&:last)] }.
map { |k, v_ary| [k, v_ary.map.with_index { |v, i| [v,i+1] }] }
视图:
<%= f.select :location_id grouped_options_For_select(@grouped_locations)
上面的代码为我提供了一个带有重复值的选择字段,如下所示:
<optgroup label="Area1">
<option value=1>Location 1</option>
<option value=2>Location 2</option>
<option value=3>Location 3</option>
</optgroup>
<optgroup label="Area2">
<option value=1>Location 4</option>
<option value=2>Location 5</option>
<option value=3>Location 6</option>
</optgroup>
如何设置grouped_locations
数组以使值不重复,如第一个示例所示?
答案 0 :(得分:1)
map.with_index
部分是索引从每个区域的0开始的位置。所以你需要跟踪索引:
i = 0
@grouped_locations = \
Location.pluck(:area, :name).group_by(&:first).
map{ |k, v_ary| [k, v_ary.map(&:last)] }.
map{ |k, v_ary| [k, v_ary.map{ |v| [v, (i += 1)] }] }
最后两个map
可以将BTW合并为一个map
:
map do |k, v_ary|
[k, v_ary.map{ |v| [v.last, (i += 1)] }]
end
这应该可以解决问题。
但我建议只使用ID作为值,避免使用多个map
来迭代结果。
@grouped_locations = \
Location.pluck(:area, :id, :name).each_with_object({}) do |location, hash|
area, id, name = location
(hash[area] ||= []) << [name, id]
end.to_a # remove 'to_a' if not required by 'grouped_options_for_select'