Forum: Ruby on Rails ActiveRecord and multiple associations

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
8f3739e3b34bfea19fd381500d8a8fe6?d=identicon&s=25 Anthony Carlos (acarlos)
on 2006-04-14 06:17
(Received via mailing list)
Hello,

I have a Company that has_and_belongs_to_many Persons. A Person
has_many Emails. I want to display each Person's Email for each
Company, so I try this:

companies = Company.find(:all)
for company in companies
   persons = company.persons
   for person in persons
     puts person.email
   end
end

Unfortunately, this doesn't work correctly. Let's say the id of the
first company is 22, and the associated person's id is 218.
ActiveRecord is retrieving from the Emails table where the owner =
22, NOT where the owner = 218, or the id of the Person.

Is this the way that ActiveRecord is supposed to work? I thought that
when I ask for an associated object, that object would be related to
the object that is associated to it, not an object higher up in the
hierarchy.

What's the best work-around for this, or am I on the wrong path?

Thanks,

-Anthony
19a59374b3191db08985d832886ed180?d=identicon&s=25 Martin Blaha (pytlik)
on 2006-04-14 08:40
(Received via mailing list)
With Rails release 1.1 I've started using has_many :xxxx, :through =>
:yyyy,
which helped me to avoid similar problems (especially with HABTM
definitions). So, nowadays I would set up your model in this way:

class Company < ActiveRecord::Base
  has_many :employees
  has_many :people, :through => :employees
end

class Person < ActiveRecord::Base
  has_many :emails

  has_many :employees
  has_many :companies, :through => :employees
end

class Employee < ActiveRecord::Base
  belongs_to :person
  belongs_to :company
end

class Email < ActiveRecord::Base
  belongs_to :person
end

With this setup, the query you've described should work.
There is one more thing ... puts person.email won't work, because this
statement doesn't specify WHICH email has to be shown. So, instead,
either
you go through the whole array (for email in emails ...) or something
like:
puts(person.emails.find(:first))

I'm quite new to Rails, but I hope that this can help.
Martin
This topic is locked and can not be replied to.