options_from_collection_for_select
options_from_collection_for_select(collection, value_method, text_method, selected_value = 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. If selected_value is specified, the element returning a match on value_method will get the selected option tag.
Example (call, result). Imagine a loop iterating over each person in @project.people to generate an input tag:
options_from_collection_for_select(@project.people, "id", "name") <option value="#{person.id}">#{person.name}</option>
NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
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)) %>
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”)) %>
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).
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.
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.
`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'.