This works with the following: options = [{:label => "something", :value => 1, :disabled => true}, {:label => "something_else", :value => 2}] my_options = options.map {|item| [item[:label], item[:value], item[:disabled]]} options_for_select(my_options) ----- ... or (options and values are the same): options = [{:label => "something", :disabled => true}, {:label => "something_else"}] my_options = options.map {|item| [item[:label], item[:disabled]]} options_for_select(my_options) ----- .. and with just a string: options = [{:label => "something"}, {:label => "something_else"}] my_options = options.map {|item| item[:label]} options_for_select(my_options) ////////////////////////////////////////////////////// def options_for_select(container, selected = nil) container = container.to_a if Hash === container options_for_select = container.inject([]) do |options, element| text, value, disabled = option_text_and_value(element) selected_attribute = ' selected="selected"' if option_value_selected?(value, selected) disabled_attribute = ' disabled="disabled"' if disabled options << %() end options_for_select.join("\n") end def option_text_and_value(option) # Options are [text, value] pairs or strings used for both. if !option.is_a?(String) and option.length == 3 [option.first, option.second, option.last] elsif !option.is_a?(String) and option.length == 2 [option.first, option.first, option.last] else [option, option, nil] end end