joining/referencing tables

Hey Scott,

That's a pretty easy set up. You won't have to do any joins, Rails
will take care of everything for you :slight_smile:

Anyway, now that you've got the tables set up, you can use AR's has_*
and belongs_to methods to set up the associations.

class Product
  has_many :comments

class Comment
  belongs_to :user

You can set up the reverse associations if you want/need to.

This code will let you do something like:

p = Product.find 1
p.comments.first.user.username # 'dopey'

comments of course is the collection of all comments, and for each
comment you have access to the user object.

Now one problem is that if you have 1 product with 10 comments, you'll
end up making 21 db calls. 1 for the product itself, 10 for each of
the comments, and 10 for the associated user. Fortunately Rails lets
you eager load the assocations.

p = Product.find 1, :include => :comments

will take care of the join for you to include comments, so they're
fetched along with the product. You can also go as deep as you need:

p = Product.find 1, :include => [ :comments => :user ]

This will fetch all the data you need in one query.


I'm not sure what you mean, honestly. has_many and belongs_to rely on
there being a foreign key. The comments table would have a product_id
foreign key to products, as well as a user_id key to users. Having
those keys and the corresponding has_many and belongs_to statements
set up the relationship to be used programmatically.

I don't know how you would automatically load the associations without
:include. Why do you want to?

The best I think you could do is to write a new finder or override the
default finder, this way you can encapsulate the call.

class Product < ActiveRecord::Base
  def self.heavy_find(id, options = {})
    find(id, { :include => [ :comments => :users ] }.merge(options))


  def self.find(id, options = {})
    super(id, { :include => [ :comments => :users ] }.merge(options))



Funny, was
*just* published to the rails plugins repository. Looks like it ought
to do exactly what you want.