A question about associations

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?

On Nov 27, 2007 11:42 AM, Krzysztof Wrzalik
[email protected] wrote:

Any ideas?
:through does this.


Greg D.
http://destiney.com/

Greg D. wrote:

On Nov 27, 2007 11:42 AM, Krzysztof Wrzalik
[email protected] wrote:

Any ideas?
:through does this.


Greg D.
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.

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:inmethod_missing’
from (irb):5
from :0

On Nov 27, 2007 12:32 PM, Krzysztof Wrzalik
[email protected] 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


Greg D.
http://destiney.com/

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


Josh S.
http://blog.hasmanythrough.com

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


Josh S.
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.

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