# Understanding :through =\> ... :source =\>

**URL:** <https://www.ruby-forum.com/t/understanding-through-source/109703>\
**Category:** Rails\
**Created:** [July 18, 2007, 4:48am UTC](https://www.ruby-forum.com/t/understanding-through-source/109703 "2007-07-18T04:48:26Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![sshefer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sshefer](https://www.ruby-forum.com/u/sshefer)\
**Post date:** [July 18, 2007, 4:48am UTC](https://www.ruby-forum.com/t/understanding-through-source/109703/1 "2007-07-18T04:48:26Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![sshefer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sshefer](https://www.ruby-forum.com/u/sshefer)\
**Post date:** [July 18, 2007, 6:15am UTC](https://www.ruby-forum.com/t/understanding-through-source/109703/2 "2007-07-18T06:15:37Z")

</div>

On 7/17/07, Shai S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)

---

<div class="post-metadata">

**Author:** ![sshefer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@sshefer](https://www.ruby-forum.com/u/sshefer)\
**Post date:** [July 18, 2007, 4:45pm UTC](https://www.ruby-forum.com/t/understanding-through-source/109703/3 "2007-07-18T16:45:15Z")

</div>

:class\_name was just what I was looking for!

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

> **[Ruby Programming](https://www.thoughtco.com/ruby-programming-4133469)**
>
> Learn the Ruby programming language with simple, step-by-step tutorials.
