Ruby on Rails
HowToUseALookUpTable

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.