Assume that you have the following lookup table:
CREATE TABLE experience_levels
(
id int PRIMARY KEY not null,
name varchar(255)
);
Now, assume that you have the following table that references the lookup table:
CREATE TABLE lessons
(
id int PRIMARY KEY not null,
title varchar(255),
experience_level_id int,
created_at datetime,
updated_at datetime
);
Your model for the lookup will be:
class ExperienceLevel < ActiveRecord::Base
has_one :lesson
#other associations here...
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 255
# other validations and methods here
end
And the model for the object that references the lookup table will be:
class Lesson < ActiveRecord::Base
# other associations here...
belongs_to :experience_level
validates_presence_of :experience_level_id
validates_numericality_of :experience_level_id
# other validations and methods here
end
Now assume you have a view that needs to display this information in a form for the Lesson entity (i.e. form_for).
Assume your controller for the lesson has an edit action. You need to look up the values from ExperienceLevel here:
def edit
@experience_levels = ExperienceLevel.find(:all, :order => :id)
# other stuff here
end
edit.rhtml will have the following inside the form block: (note the “Please select” prompt gives a standard look for the dropdown):
<% label = content_tag("label", "Experience Level",
:for => "experience_level_experience_level_id")
form_field = collection_select("lesson", "experience_level_id",
@experience_levels, "id", "name", :prompt => "Please select")
%>
<%= content_tag("div", "#{label} #{form_field}") %>
This will set up the params hash correctly so you can simply create with Lesson.create(params[:lesson]) or update attributes with update_attributes(params[:lesson]).
If you need to reference the lookup outside an entity form (such as in a search), you have to collect the values. For example:
def index
experience_levels = ExperienceLevel.find(:all, :order => :id)
@experience_level_coll = experience_levels.collect { |t| [t.name, t.id]}
end
To use this in a view, you will use a slightly different collection helper. For example:
<% form_tag({ :action => :lesson_search }, :method => "get") do %>
<fieldset>
<legend>Search Lessons</legend>
<% label = content_tag(:label, "Experience level: ", :for => :el)
my_collection = @experience_level_coll
my_collection.insert(0, ["Please select", ""])
form_field = content_tag(:select,
options_for_select(my_collection, params[:el].to_i),
:name => :el) %>
<%= content_tag("div", "#{label} #{form_field}", :class => "form_row") %>
<input type="submit" value="Search" />
</fieldset>
<% end %>
Then, extract the ID out in the actual search action:
def lesson_search
@lessons = Lesson.find_all_by_experience_level_id(params[:el]) if params[:el]
# paginate, redirect, etc.
end
Hope this helps. Feel free to add clarifications or improvements-I crafted this up on my own and I am still new to Rails.