Rails 1.0 is great, but 1.1 additions have made web dev even easier. One of the nice new features of 1.1 is has_many :through. A nice tutorial of hm:t can be found at blog.hasmanythrough.com (Part 1 & Part 2).
What i would like to cover is how to use a lookup (association/relationship) table on top of the hm:t feature.
For example, I have a table of `users` and a table of `reports`. Since multiple users can contribute to the report, we add a third table `contributions`.
class User < ActiveRecord::Base
has_many :contributions, :dependent => true
has_many :reports, :through => :contributions
end
class Report < ActiveRecord::Base
has_many :contributions, :dependent => true
has_many :users, :through => :contributions
end
class Contributions < ActiveRecord::Base
belongs_to :user
belongs_to :report
end
Looks just like the example I linked to you say & you’re right! But, that’s not all. My customer now wants to categorize the reports. So we make a simple lookup table called `report_types`. It has `id`, `report_type_name`, `created_on`, & `updated_on` fields. We then add the field `report_type_id` to the `reports` table. Next we generate a model for `report_types` & then add
has_many :reports
to the ReportType class (report_type.rb) and we add
belongs_to :report_type
to the Report class we previously created.
If you have more than one lookup table just repeat the above procedure for adding more lookup tables.
So we now have everything setup properly, but how do we output the value from the lookup table? Quite easily in fact. We’ll look at two examples. First we are going to display all report contributions for all users. So we generate a new controller called `reports`. Then we create an index method.
class ReportController < ApplicationController
def index
@reports = Report.find_all
end
end
we then add another method `by_user` to the `Report` controller which will display reports contributed to by a single user.
def index
@writer = User.find(@params["id"])
# assume the id is passed as a parameter
@reports = @writer.reports.find_all
end
Now that we gotten our data out of the database, how do i display the actual report type and not the id you ask? It’s as simple as adding the line
inside a loop such as:
@reports.each do |userreport|
<%= userreport.report_type.report_type_name %>
end of loop
anywhere in your rhtml file. The important thing is to remember to use the association that you put in the belongs_to statement and not the class name.
<@instancevar>.<association>.<association_field>
And there you have it. Lookup table data while using hm:t. Have fun coding!