简体   繁体   中英

Ruby on Rails - Add select options grouped by column

Let's say I have a table with 2 fields: "Type" and "Name"

Is there a way I can create a dropdown that shows something like:

Type A
    All of the db entries that have Type A
Type B
    All of the db entries with Type B

How can I do this? I've been looking at grouped_collection_set, but the examples only appear to group the options based on db associations. In this case I'm just using one table, not two.

Create a class method.

So using option_groups_from_collection_for_select won't help you here. It's expecting you to have the option group be one model and the option be another model.

What you want is grouped_options_for_select and to use a class method to generate the required nested arrays to fulfill its wishes.

Going on what your original question posted, you'll want to add something like this to the model:

def self.select_options_grouped_by_type
  self.uniq.pluck(:type).sort.collect do |type| 
    [ 
      type, 
      YourModel.where( type: type ).collect { |record| [ record.name, record.id ] }
    ] 
  end 
end

This will get you a nested array that looks something like this:

[
  [ "Type A", [ 
    [ "Name 1", 1 ], 
    [ "Name 2", 2 ], 
    ... ],
  [ "Type B", [
    [ "Name 3", 3 ],
    [ "Name 4", 4 ],
    ... ],
  ]
  ...
]

Then you just feed that into grouped_options_for_select :

<%= grouped_options_for_select( YourModel.select_options_grouped_by_source ) %>

And you'll generate generate the optgroup and option tags:

<optgroup label="Type A">
  <option value="1">Name 1</option>
  <option value="2">Name 2</option>
  <!-- ... -->
</optgroup>
<optgroup label="Type B">
  <option value="3">Name 3</option>
  <option value="4">Name 4</option>
  <!-- ... -->
</optgroup>
<!-- ... -->

One-liner:

def self.select_options_grouped_by_type
  self.uniq.pluck(:type).sort.collect{ |type| [ type, YourModel.where( type: type ).collect{ |record| [ record.name, record.id ] } ] }
end

Hope that helps others.

You can use:

options_from_collection_for_select(collection, value_method, text_method, selected = nil)

Documentation

Then pass 2 instance variables (eg @modeTypeA = Model.where(type: "A")) to your views to use in your collection. So a possible implementation would be something like:

<select>
    <%= options_from_collection_for_select(@modeTypeA, 'id', 'name') %>
</select>
<select>
   <%= options_from_collection_for_select(@modeTypeB, 'id', 'name') %>
</select>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM