Dynamically add includes to an association?

I have an association user.lessons. Sometimes i just want the lessons,
other times i want the lessons to eager-load one of their own
associations, ‘assets’. Theres a couple of ways i can see to deal with
this and i’m not super happy with any of them.

approach 1) Make two associations:
has_many :lessons
has_many :lessons_with_assets, :class_name => “Lesson”, :include =>
[:assets]

#then, if i want the assets, call
@user.lessons_with_assets

This is actually my favorite but it still feels a bit clumsy

approach 2) Don’t use the association if i want to eager load
#just do a regular find
Lesson.find_all_by_user_id(@user.id, :include => [:assets])

Is there another way? This example is simple but i have other
associations that go through join tables and are polymorphic (eg using
the has_favorite plugin) that are a bit more arsey to use.

thanks
max

On Thu, Jan 22, 2009 at 12:38 PM, Max W. <
[email protected]> wrote:

associations that go through join tables and are polymorphic (eg using
the has_favorite plugin) that are a bit more arsey to use.

thanks
max

Posted via http://www.ruby-forum.com/.

Max

There’s another way, named_scopes.

in the Lesson model, add
named_scope :with_assets, :include => :assets

then you can call
lessons
or
lessons.with_assets


Andrew T.
http://ramblingsonrails.com
http://www.linkedin.com/in/andrewtimberlake

“I have never let my schooling interfere with my education” - Mark Twain

aha…so, if i have lots of different associations (in user and other
classes) that return a collection of lessons i can just add
“.with_assets” to the end? eg

user.usb_lessons.with_assets

user.lessons.with_assets

resource.recent_lessons.with_assets

etc
?

After a bit of experimentation i confirmed for myself that that is
indeed the case :slight_smile:

thanks a lot Andrew, this is great. I’d seen named scopes before but
never really used them much and never realised their potential for
managing includes.

One thing i noticed which is interesting…lessons are joined to assets
through a join table, ‘elements’.

if i use the with_assets scope for an association that goes through a
join table, then rails does a further join to the assets table, like
you’d expect with an include, so we have this situation:

user JOIN user_usb_lessons JOIN lessons JOIN elements JOIN assets

If, however, it’s a simple association (such as user.lessons, which just
uses Lesson’s user_id field) then rails splits it off into three sql
calls: the first to load the lessons, the second to load the elements
(join table records) and the third to load the assets.

I guess that three seperate simple calls were seen as preferable to a
single JOIN?

Anyway, thanks again!
max

On Thu, Jan 22, 2009 at 1:58 PM, Max W. <
[email protected]> wrote:

I guess that three seperate simple calls were seen as preferable to a
single JOIN?

Anyway, thanks again!
max

Posted via http://www.ruby-forum.com/.

Yes, on more complicated joins, where Rails thinks it will be better, it
does split the query into multiple queries.


Andrew T.
http://ramblingsonrails.com
http://www.linkedin.com/in/andrewtimberlake

“I have never let my schooling interfere with my education” - Mark Twain

On 22 Jan 2009, at 11:08, Andrew T. wrote:

then you can call
lessons
or
lessons.with_assets

See also
http://ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know

Fred