# Has\_many through question

**URL:** <https://www.ruby-forum.com/t/has-many-through-question/121998>\
**Category:** Rails\
**Created:** [December 3, 2007, 7:40pm UTC](https://www.ruby-forum.com/t/has-many-through-question/121998 "2007-12-03T19:40:46Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jcernelli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@jcernelli](https://www.ruby-forum.com/u/jcernelli)\
**Post date:** [December 3, 2007, 7:40pm UTC](https://www.ruby-forum.com/t/has-many-through-question/121998/1 "2007-12-03T19:40:46Z")

</div>

Hi, I have a fairly typical has\_many, through setup with a bit of a  
twist.

class Course \< ActiveRecord::Base

has\_many :placements  
has\_many :students, :through =\> :placements

end

class Student \< ActiveRecord::Base

has\_many :placements  
has\_many :courses, :through =\> :placements

end

class Placements \< ActiveRecord::Base

belongs\_to :course  
belongs\_to :student

end

So with this I could grab all the students for a course by:

@students = @course.students

Everything is fine so far, but here is the twist. I have to narrow  
things  
down by some data on the placements table. Let’s say I have a column  
called  
“placed\_by” on “Placements”

How would I retrieve all of the students for a course if I only wanted  
to  
see those who were placed by “Bob” for example?

---

<div class="post-metadata">

**Author:** ![jcernelli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@jcernelli](https://www.ruby-forum.com/u/jcernelli)\
**Post date:** [December 3, 2007, 7:53pm UTC](https://www.ruby-forum.com/t/has-many-through-question/121998/2 "2007-12-03T19:53:27Z")

</div>

two possible ways:

1. if the condition has to be met every time:

has\_many :students, :through =\> :placements, :conditions =\> {:placed\_on  
=\> ‘you\_value’}

1. more likely and more flexible the “association extensions”:

has\_many :students, :through =\> :placements do  
def placed\_by(who)  
find\_all\_by\_placed\_by(who)  
end  
end

can be called:  
@students = @course.students.placed\_by(who\_id)

---

<div class="post-metadata">

**Author:** ![jcernelli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@jcernelli](https://www.ruby-forum.com/u/jcernelli)\
**Post date:** [December 3, 2007, 8:20pm UTC](https://www.ruby-forum.com/t/has-many-through-question/121998/3 "2007-12-03T20:20:44Z")

</div>

Thanks, #2 nails it! Would it be roughly the same if there were two or  
three unrelated fields on there? Something like:

has\_many :students, :through =\> :placements do  
def find\_by(who, when)  
find(:all, :conditions =\>[‘placed\_by = ?, created\_on \>= ?’,who,  
when])  
end  
end

@students = @course.students.find\_by(who\_id, datetime)

On Dec 3, 2007 1:53 PM, Thorsten M.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![jcernelli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@jcernelli](https://www.ruby-forum.com/u/jcernelli)\
**Post date:** [December 3, 2007, 8:27pm UTC](https://www.ruby-forum.com/t/has-many-through-question/121998/4 "2007-12-03T20:27:00Z")

</div>

Joe C. wrote:

> Thanks, #2 nails it! Would it be roughly the same if there were two or  
> three unrelated fields on there? Something like:
> 
> has\_many :students, :through =\> :placements do  
> def find\_by(who, when)  
> find(:all, :conditions =\>[‘placed\_by = ?, created\_on \>= ?’,who,  
> when])  
> end  
> end
> 
> @students = @course.students.find\_by(who\_id, datetime)
> 
> On Dec 3, 2007 1:53 PM, Thorsten M.  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

yes, you can place any code you like in this method, as long as it  
returns something that’s usable as a student (in this case) 😉

you can use the finder functions or find\_by\_sql for really hard work  
in theory it should even be possible to return an array of hashes, that  
contain all the necessary columns as keys  
[{name =\> “student1”, :location =\> “Washington” …}, {:name =\> “student  
two”, …}]  
but i never tried that last one myself

---

<div class="post-metadata">

**Author:** ![jcernelli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@jcernelli](https://www.ruby-forum.com/u/jcernelli)\
**Post date:** [December 3, 2007, 11:50pm UTC](https://www.ruby-forum.com/t/has-many-through-question/121998/5 "2007-12-03T23:50:59Z")

</div>

What about something a little different?  
Is there a way to process 2 levels deep?  
so @all\_courses = @students.courses  
In SQL that could be an IN() statement composed of student IDs.

On Dec 3, 2:27 pm, Thorsten M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
