# A question about associations

**URL:** <https://www.ruby-forum.com/t/a-question-about-associations/121407>\
**Category:** Rails\
**Created:** [November 27, 2007, 6:42pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407 "2007-11-27T18:42:29Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 6:42pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/1 "2007-11-27T18:42:29Z")

</div>

Is it possible to get the ‘other’ end of an associations? For example if  
teacher has\_many students, it could be very readable to say something  
like this:

ateacher.students[0].classes

which would call a method on the student that would list classes of the  
teacher that student goes to

Any ideas?

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 7:06pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/2 "2007-11-27T19:06:09Z")

</div>

On Nov 27, 2007 11:42 AM, Krzysztof Wrzalik  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Any ideas?  
> :through does this.

–  
Greg D.  
[http://destiney.com/](http://destiney.com/)

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 7:32pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/3 "2007-11-27T19:32:49Z")

</div>

Greg D. wrote:

> On Nov 27, 2007 11:42 AM, Krzysztof Wrzalik  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Any ideas?  
> > :through does this.
> 
> –  
> Greg D.  
> [http://destiney.com/](http://destiney.com/)

Could you please provide an example and explain how this corresponds to  
my question? For example how to get to the teacher object in classes  
method of student.

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 8:19pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/4 "2007-11-27T20:19:19Z")

</div>

> Can you please provide your own failed attempt first?

class Teacher \< ActiveRecord::Base  
has\_many :connections  
has\_many :students, :through =\> :connections  
end

class Student \< ActiveRecord::Base  
has\_many :connections  
has\_many :teachers, :through =\> :connections  
end

class Connection \< ActiveRecord::Base  
belongs\_to :teacher  
belongs\_to :student  
end

> > t=Teacher.find\_first  
> > =\> #\<Teacher:0xb708d2e0 @attributes={“name”=\>“Arkadiusz Jankowski”,  
> > “id”=\>“0”}
> 
> > s=Teacher.find\_first.students.first  
> > =\> #\<Student:0xb71ba4d8 @attributes={“name”=\>“Dawid Michalski”,  
> > “id”=\>“3”}
> 
> > s.teacher  
> > NoMethodError: undefined method `teacher' for #<Student:0xb71ba4d8> from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1860:in`method\_missing’  
> > from (irb):5  
> > from :0

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 7:38pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/5 "2007-11-27T19:38:59Z")

</div>

On Nov 27, 2007 12:32 PM, Krzysztof Wrzalik  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Could you please provide an example

Can you please provide your own failed attempt first?

> and explain how this corresponds to  
> my question?

[http://www.google.com/search?q=rubyonrails+%3Athrough](http://www.google.com/search?q=rubyonrails+%3Athrough)

–  
Greg D.  
[http://destiney.com/](http://destiney.com/)

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 8:33pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/6 "2007-11-27T20:33:06Z")

</div>

Krzysztof Wrzalik wrote:

> > Can you please provide your own failed attempt first?
> 
> class Teacher \< ActiveRecord::Base  
> has\_many :connections  
> has\_many :students, :through =\> :connections  
> end
> 
> class Student \< ActiveRecord::Base  
> has\_many :connections  
> has\_many :teachers, :through =\> :connections  
> end
> 
> class Connection \< ActiveRecord::Base  
> belongs\_to :teacher  
> belongs\_to :student  
> end
> 
> > > t=Teacher.find\_first  
> > > =\> #\<Teacher:0xb708d2e0 @attributes={“name”=\>“Arkadiusz Jankowski”,  
> > > “id”=\>“0”}  
> > > s=Teacher.find\_first.students.first  
> > > =\> #\<Student:0xb71ba4d8 @attributes={“name”=\>“Dawid Michalski”,  
> > > “id”=\>“3”}  
> > > s.teacher  
> > > NoMethodError: undefined method `teacher' for #<Student:0xb71ba4d8> from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1860:in `method\_missing’  
> > > from (irb):5  
> > > from :0

Student doesn’t have a singular teacher, so that’s your problem. If you  
want to get the connection object between a teacher and student, you can  
do something like

@teacher.connection.find\_by\_student\_id(@student.id)

I’ve got a discussion of this and how to make it a little prettier on my  
blog:  
[http://blog.hasmanythrough.com/2006/6/30/working-with-the-relationship-model](http://blog.hasmanythrough.com/2006/6/30/working-with-the-relationship-model)

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 9:14pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/7 "2007-11-27T21:14:35Z")

</div>

Josh S. wrote:

> @teacher.connection.find\_by\_student\_id(@student.id)
> 
> I’ve got a discussion of this and how to make it a little prettier on my  
> blog:  
> [has\_many :through - Working with the relationship model](http://blog.hasmanythrough.com/2006/6/30/working-with-the-relationship-model)
> 
> –  
> Josh S.  
> [http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

I’ve come to the following ‘sub-solution’:

class Teacher \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :students

def student  
if @attributes[:student\_id]  
raise “Teacher#student requires a call through association”  
end  
Student.find(student\_id)  
end  
end

class Student \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :teachers

def teacher  
if @attributes[:teacher\_id]  
raise “Student#teacher requires a call through association”  
end  
Teacher.find(teacher\_id)  
end  
end

now:

> > t=Teacher.find\_first  
> > =\> #\<Teacher:0xb6eafd24 @attributes={“name”=\>“Arkadiusz Jankowski”,  
> > “id”=\>“0”}  
> > s=t.students.first  
> > =\> #\<Student:0xb6e6b4a8 @readonly=true, @attributes={“name”=\>“Dawid  
> > Michalski”, “student\_id”=\>“3”, “id”=\>nil, “teacher\_id”=\>“0”}  
> > s.teacher  
> > =\> #\<Teacher:0xb7035c0c @attributes={“name”=\>“Arkadiusz Jankowski”,  
> > “id”=\>“0”}

This uses the fact I discovered that has\_and\_belongs\_to\_many  
automagically adds columns from association table into the result of  
association call. Seems to me it is done so by omission, but proves  
helpful. The problems are that you have to perform additional  
unnecessary query to that database and that it can be used only with  
has\_and\_belongs\_to\_many. I’d really see a methods like teacher and  
student added to the object by ActiveRecord like students and teachers  
collections are. If someone has any ideas, I’d be grateful to know.

---

<div class="post-metadata">

**Author:** ![kyku](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/34f0e0/32.png) [@kyku](https://www.ruby-forum.com/u/kyku)\
**Post date:** [November 27, 2007, 9:26pm UTC](https://www.ruby-forum.com/t/a-question-about-associations/121407/8 "2007-11-27T21:26:38Z")

</div>

> class Teacher \< ActiveRecord::Base  
> has\_and\_belongs\_to\_many :students
> 
> def student  
> if @attributes[:student\_id]  
> raise “Teacher#student requires a call through association”  
> end  
> Student.find(student\_id)  
> end  
> end
> 
> class Student \< ActiveRecord::Base  
> has\_and\_belongs\_to\_many :teachers
> 
> def teacher  
> if @attributes[:teacher\_id]  
> raise “Student#teacher requires a call through association”  
> end  
> Teacher.find(teacher\_id)  
> end  
> end

sorry it should read:

class Teacher \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :students

def student  
unless @attributes[‘student\_id’]  
raise “Teacher#student requires a call through association”  
end  
Student.find(student\_id)  
end  
end

class Student \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :teachers

def teacher  
puts @attributes.inspect  
unless @attributes[‘teacher\_id’]  
raise “Student#teacher requires a call through association”  
end  
Teacher.find(teacher\_id)  
end  
end
