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

Returns a string of option tags that have been compiled by iterating over the collection and assigning the the result of a call to the value_method as the option value and the text_method as the option text. Example:

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

This will output the same HTML as if you did this:

  <option value="#{person.id}">#{person.name}</option>

This is more often than not used inside a #select_tag like this example:

  select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')

If selected is specified as a value or array of values, the element(s) returning a match on value_method will be selected option tag(s).

If selected is specified as a Proc, those members of the collection that return true for the anonymous function are the selected values.

selected can also be a hash, specifying both :selected and/or :disabled values as required.

Be sure to specify the same class as the value_method when specifying selected or disabled options. Failure to do this will produce undesired results. Example:

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

Will not select a person with the id of 1 because 1 (an Integer) is not the same as ‘1’ (a string)

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

should produce the desired results.

Show source
Register or log in to add new notes.
March 6, 2009
2 thanks

Selected parameter needs an int

In order to pre-select an option, you can pass a fourth parameter. However, that parameter MUST be of integer type, so if you’re trying to set selected from the params hash, you must add to_i at the end of it.

<%= select_tag("job[state_id]", options_from_collection_for_select(State.find(:all), "id", "name", params[:state_id].to_i)) %>
July 22, 2008
1 thank

Full Select

The full select using this would be something like:

Code Example

<%= select_tag(“job[state_id]”, options_from_collection_for_select(State.find(:all), “id”, “name”)) %>

March 12, 2009
1 thank

Selected parameter

batasrki’s note on “selected” parameter is only true for cases which “value_method” returns an int also.

The strictly correct requirement for it to work is:

object.value_method == selected

(“object” is the current object on the iteration over collection)

Since the params hash returns Strings, using it against a value_method with return type of int will never give a valid match (thus no auto-selection is done), i.e., “13” != 13.

When you’ll be using other types of value_method, like String, there’s no need to append “.to_i”, e.g:

options_from_collection_for_select(@posts, "slug", "title", params[:slug])

where “slug” is a String, it will work as expected (current selected post is auto-selected by default).

November 6, 2012
0 thanks

Selected parameter

If you want multiple options to be selected by default you can pass an array of values as “selected” option. It should be obvious, but odradek’s and batarski’s notes can confuse somebody in this case.

February 3, 2014
0 thanks

Symbols more performant than strings

>> options_from_collection_for_select(@posts, :slug, :title, params[:slug])

Consider using symbols for performance, otherwise it will generate a string each time instead of a symbol which will reference the same object.

April 12, 2016
0 thanks

`value` or `text` method with parameter.

If your value or text method requires a parameter, like to_s(:select) then you need to create a separate method that references that in your model, like:

def to_s_select
  to_s(:select)
end

You can’t pass it in as a string like 'to_s(:select)'.

You have to use :to_s_select or 'to_s_select'.