3

I've seen a few examples of passing an :include hash value when calling one of ActiveRecord's find methods in Rails. However, I haven't seen any examples of whether this is possible via relationship methods. For example, let's say I have the following:

def User < ActiveRecord::Base
  has_many :user_favorites
  has_many :favorites, :through => :user_favorites
end

def Favorite < ActiveRecord::Base
  has_many :user_favorites
  has_many :users, :through => :user_favorites
end

def UserFavorite < ActiveRecord::Base
  belongs_to :user
  belongs_to :favorite
end

All the examples I see show code like this:

User.find(:all, :include => :favorite)

But I don't see any examples showing the use of relationships. Would it instead be possible for me to do something like this?

User.favorites(:include => :user)
Richard Garside
  • 87,839
  • 11
  • 80
  • 93
Matt Huggins
  • 81,398
  • 36
  • 149
  • 218

2 Answers2

6

You can't use relations as Class methods. It is instance methods. You can call

@user.favorites

Check out this screencast about Eager Loading

http://railscasts.com/episodes/22-eager-loading

It will be

 User.find(:all, :include => :favorites)

or for Rails 3.x

 User.includes(:favorites)
Dty
  • 12,253
  • 6
  • 43
  • 61
fl00r
  • 82,987
  • 33
  • 217
  • 237
  • That didn't answer the question of whether I can use a relationship method instead of the `find` method. – Matt Huggins Mar 27 '11 at 20:59
  • That's too bad, kind defeats some of the simplicity of Rails. Thanks for the info. – Matt Huggins Mar 27 '11 at 21:18
  • No it is quite natural, you just need to feel it :) – fl00r Mar 27 '11 at 21:19
  • I guess what I'm saying is that it defeats the purpose of the relationship methods. If I'm always going to be calling `Class.find` instead of `instance.relationship`, then there's no reason for there to be a relationship method in the first place other than to define the entity relationship structure. – Matt Huggins Mar 27 '11 at 21:25
  • What should `Class.relationship` return? All classes with all related relationships? Ehmm...? – fl00r Mar 27 '11 at 21:27
  • 2
    No, I'm saying `instance.relationship(:include => ...)` should essnentially do the same as `Class.find(:all, :include => ...)`, except that it should be scoped to the instance. The way it is now, I have to manually scope the query when calling `Class.find` if I also want to benefit from the use of the `:include` option. – Matt Huggins Mar 27 '11 at 21:32
  • Maybe you're right, but what should `Class.relationship` use `joins` or `includes`? I mean which SQL JOIN it should use? – fl00r Mar 27 '11 at 21:36
1

You can add :include to your model's associations to eager load the second-order associations when the object is loaded.

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

Christopher Manning
  • 4,527
  • 2
  • 27
  • 36