Relationships

Question:
company_user belongs to user, and belongs to company. Then, document
belongs to company.

I want to take a user, and grab all of the companies he belongs to, and
also grab all of the documents of those companies.

So I want to take user_id, grab the corrosponding company_users, then
from there use the company_users' company_id to grab the companies,
then from there use the company_id in documents to match up with those
companies and grab them.

How do I do that?

Thanks for your time!
Ben Lisbakken

First off you want

class Company < ActiveRecord::Base
has_and_belongs_to_many :users
# ...
end

class User < ActiveRecord::Base
has_and_belongs_to_many :companies
# ...
end

user = User.find(params[:id]) # assuming a request
companies = user.companies
user_documents = {}
companies.each { |company|
  user_documents[company.name] = company.documents # use whatever key
is convenient for you
}

Question:
company_user belongs to user, and belongs to company. Then, document
belongs to company.

I assume you have models that look something like this.

class User < ActiveRecord::Base
  has_many :company_users
  has_many :companies, :through => :company_users
end

class Company < ActiveRecord::Base
  has_many :company_users
  has_many :users, :through => :company_users
  has_many :documents
end

class CompanyUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :company
end

class Document < ActiveRecord::Base
  belongs_to :company
end

I want to take a user, and grab all of the companies he belongs to, and
also grab all of the documents of those companies.

If you have a user, you should be able to simply do the following.

companies = user.companies

if companies.nil?
  # deal with the case where no companies were found
else
  for company in companies
    documents = company.documents
   # Do whatever with documents.
  end
end

-- James

I haven't read your responses, but here are my models. I'll read them
in just a sec... thanks for the quick and great feedback!

class User < ActiveRecord::Base
  has_many :company_users
end

class CompanyUser < ActiveRecord::Base
  belongs_to :company
  belongs_to :user
end

class Company < ActiveRecord::Base
  has_many :company_users
  has_many :documents
end

class Document < ActiveRecord::Base
  belongs_to :company
end

-Ben

Cool I read both of yours... James yours is more like what I did. I
was trying to see if this could be done in one sql statement to grab
alllll of it.

Brian, would you suggest I get rid of the company_users table? What
fields would I need to add to companies and users?

Thanks again guys!
Ben

Oops I was confused. Leaving company_users in, and using :through.
Can I do habtm :through?

errr no… don’t get rid of the company_user table. You need it.

has_and_belongs_to_many is used for pure join tables where it contains just two foreign keys

has_many :through is for join tables that contain additional data, i.e. it’s intended to be used as another full-fledged model

Don’t think in terms of SQL anymore. Let rails handle it. The associations are what let rails automagically generate the SQL statements for you. If you tail -f your development.log you’ll see.

You need the table. What you might not need to do is explicitly
define the model. That's the main difference between Brian's code and
the code I posted. If companies_users stores only the appropriate
foreign keys, then use Brian's method. If you need to store more info
for a user-company relationship, then my way will work.

-- James

It can. Using either Brian's or James' setup, you can do:

user.companies.find(:all, :include => :documents)

Pete Yandell