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.
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
0 thanks

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).

March 6, 2009 - (>= v2.0.2)
0 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)) %>