<%= collection_select("job", "client_id" , @clients, "id", "name") %>clients = Client.find_all to get the clients collection or you can put the "Client.find_all" directly into the collection_select instead of "clients". Like this <%= collection_select :Job, :client_id, Client.find(:all), :id, :name %>).<select name="job[client_id]">
<option value="1">Francisco Hernandez
select() is meant to operate on ActiveRecord object instances, or, more generally, any class instance which has read accessor methods, à la attr_reader.
ex1:
select (:artists, :name, @deadArtists)
will create a drop-down select list for all of the artists in @deadArtists. Each deadArtist is checked to see if they match the value of @artists.name. If they match, they will be selected in the created drop-down list.
You say you want to use some other data structure – a hash or an array – and you are determined to use the select() helper function? You can either force your data into a data structure that can be accessed via the dot-accessor (e.g., by using the Struct object), or you can use the :selected option.
ex2:
#controller:
@SiteLanguages = ['en', 'de', 'fr']
...
pLanguages = params[:languages]
@languages = Struct.new(:language).new(pLanguages['language'])
#view:
<%= select :languages, :language, @SiteLanguages %>
The compact single-line syntax above could also be written as:
MyStruct = Struct.new(:language)
@languages = new MyStruct(pLanguages['language'])
ex3:
Using the :selected option
@SiteLanguages = ['en', 'de', 'fr']
@selected_language = 'en'
#view:
<%= select :languages, :language, @SiteLanguages, {:selected=>@selected_language} %>
You CAN use “options_from_collection_for_select” where the last argument is an integer to match the id of the selected item.
To force a selected value, use the :selected value
select(:lead, :months, month_map, {:selected => 6}, {}) # 6 will always be pre-selected
select(:lead, :months, month_map, {}, {}) # @lead.months [or nothing, if that's nil] will be pre-selected
Note that there is also a helper options_for_select
which yields strings like
“]
I used the select helper to give the user a choice to select the sex of a person.
The helper code is as follows:
<%= select( "member", "sex", { "male" => "M", "female" => "F"}) %>
This would render this HTML:
<select id="member_sex" name="member[sex]">
<option value="F">female
Rails would assign the values M or F for this attribute in the database, and pre-select the right value if the view is rendered for editing.
(Why does the hash get sorted, F before M? This isn’t significant here but it’s a problem with what I’m using (a huge list that needs to remain in a fixed order)
You can never be guaranteed of any order with hashes. You could try .sort() to sort the values in alphabetical order.
When trying to get multiple selected values from a <SELECT> tag into @params, call your parameter something with [] on the end. That way rails knows it’s multiple.
So instead of
<select name="job[techs]" size="5" multiple="multiple"> </pre>Use:
<select name="job[techs][]" size="5" multiple="multiple"> </pre>Example
<% @selected = @job.technician.collect { |t| t.technician_id.to_i } %> <select name="job[techs][]" size="5" multiple="multiple"> <%= options_from_collection_for_select(@techs, "id", "full_name", @selected) %> </select>Assigning to has_many or has_and_belongs_to_many collections
If you want to have your multiple choice select assign to a has_many or has_and_belongs_to_many (habtm) collection on your object, you should specify the collection using the <collection name>_ids name. For example, if we have an AddressGroup object with a collection of Address objects called addresses, we would not use this:
<select name="addressgroup[addresses][]" multiple="multiple">but rather this:
<select name="addressgroup[address_ids][]" multiple="multiple">With either select statement the returned value is an array of Address object ids, not the actual array objects, which will fail if we tried to assign to addressgroup.addresses. If you try to do that you will get an error message like “Expected Address and got String”. Instead, we use the implicit address_ids= property (automatically added to an object when it has a has_many or habtm collection), which assigns to the collection based on a collection of IDs.
options_from_collection_for_select with custom text
Sometimes you may want to use multiple attributes for the text portions of the select list. or maybe you want to munge a value in some specific way.
<select id="device_outlet" name="device[outlet]"> <option value=""></option> <%= options_from_collection_for_select @outlets.collect {|outlet| [outlet.id, outlet.powerstrip.name + ":" + outlet.name]}, 'first', 'last', @selected_outlet %> </select>By creating a collection of arrays with 2 values (the first being the option value and the second being the option text) you can munge/change/concatenate to your hearts content. The trick is use the first and last methods for an Array.
If you want you can always sort by the option text as well:
<select id="device_outlet" name="device[outlet]"> <option value=""></option> <%= options_from_collection_for_select @outlets.collect {|outlet| [outlet.id, outlet.powerstrip.name + ":" + outlet.name]}.sort{|x,y| x.last <=> y.last}, 'first', 'last', @selected_outlet %></select>— Joel Nimety
Or just add a method to the model that concatenates the fields and use that in the call to collection_for_select.
collection_select_with_current with html_options
To answer the question “How would one go about adding html options to collection_select_with_current?” Try this:
def collection_select_with_current(object, method, collection, value_method, text_method, current_value, html_options={}) result = "<select name='#{object}[#{method}]'" html_options.each do |key, value| result << ' ' + key.to_s + '="' + value.to_s + '"' end result << ">\n" for element in collection if current_value == element.send(value_method) result << "<option value='#{element.send(value_method)}' selected='selected'>#{element.send(text_method)}</option>\n" else result << "<option value='#{element.send(value_method)}'>#{element.send(text_method)}</option>\n" end end result << "</select>\n" return result endUse html_options like so:
collection_select_with_current('entry', 'author_id', @authors, 'id', 'full_name', @entry.author_id, {:class => 'my_select'})Or leave out the html_options like this:
collection_select_with_current('entry', 'author_id', @authors, 'id', 'full_name', @entry.author_id)— Chris Your
Drop-down with multiple selected items
Here is my, and hopefully the best, solution:
user.rb:
class User < ActiveRecord::Base has_and_belongs_to_many :roles endrole.rb:
class Role < ActiveRecord::Base has_and_belongs_to_many :users enduser_controller.rb:
class UserController < ApplicationController def new @user = User.new @roles = Role.find(:all) end ... def edit @user = User.find(params[:id]) @roles = Role.find(:all) end endAnd in *.rhtml, i use:
<%= collection_select('user', 'role_ids', @roles, :id, :name, {}, :multiple => true) %>— Christian Mueller
How to pass in disabled:
def select(object, method, choices, options = {}, html_options = {})
It appears that select() takes these options:So if you want it disabled, you’ll need to pass that in last, or
select(:abc, :option_name, ‘yes’, true?, {}, {:disabled => true }) to have a disabled version.Screencast on options_from_collection_for_select and multiple selected values