Understanding :through => ... :source =>

I’m trying to understand :through and :source with the following
example.

I have a User, Job, and Interview models. An interview has an
interviewer and interviewee. I would like to use the User model for
this and I assume I would have to use :source. Any ideas on where to
get started?

On 7/17/07, Shai S. [email protected] wrote:

I’m trying to understand :through and :source with the following
example.

I have a User, Job, and Interview models. An interview has an
interviewer and interviewee. I would like to use the User model for
this and I assume I would have to use :source. Any ideas on where to
get started?

Where to start? Keep your user model simple. Think about what your
views are going to show, and what the code should look like.

Interview
belongs_to :interviewer, :class_name => ‘User’
belongs_to :interviewee, :class_name => ‘User’

User
has_many :interviews

This gets tricky, does this join with interviewer_id or interviewee_id
in interviews? You probably need two different names for these joins.

User
has_many :led_interviews, :class_name => ‘Interview’, :foreign_key
=> ‘interviewer_id’
has_many :attended_interviews, :class_name => ‘Interview’,
:foreign_key => ‘interviewee_id’

I find it’s best to write some sanity tests to confirm all this. I
don’t claim that this will work…

Now for the has_many :through join:

Job
has_many :interviews
has_many :interviewers, :through => :interviews
has_many :interviewees, :through => :interviews

This doesn’t need a source, because it’s going to look at
Interview#interviewer or Interview#interviewee by default. Has_many
:through associations are unique, they actually look at the other
association (the “source” association) and use its reflection data.
That’s why there’s no :class_name or :foreign_key option required.
Here’s a simple case where :source would be used:

Comment
belongs_to :user
belongs_to article

Article
has_many :comments
has_many :users, :through => :comments

In this case, you may not want to use #users. One: it may not be
descriptive enough. Another reason is it may be too similar to
Article#user, a belongs_to association pointing to the Article’s
author. So you can do this:

Article
has_many :comments
has_many :commenters, :through => :comments

Now you’ll get some error about ActiveRecord not finding a #commenter
or #commenters association on Comment. Of course, it’s called #user
instead!

Article
has_many :comments
has_many :commenters, :through => :comments, :source => :user


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com

:class_name was just what I was looking for!

For anyone else interested in this, there is another short write up at