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 end

class Comment   belongs_to :user end

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))   end


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



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