Forum: Ruby on Rails eager loading parents and children (acts_as_tree)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5e75f4b81923cd04a5c8fffa290be92e?d=identicon&s=25 Carl Johnson (carlivar)
on 2007-02-14 09:15
I am struggling with how to do eager loading of an acts_as_tree model.

If the model Stuff acts_as_tree I know I can do this to get children as
well:

Stuff.find(:all, :include => :children)

But what if the model I am including is the one that acts_as_tree?

For example, say Picture belongs_to Category. Category acts_as_tree and
I want to get all pictures that are members of a category that belong to
a particular user and ALSO all pictures in children of those categories
(one level of children is fine). I believe this is the correct syntax:

Pictures.find(:all, :include => {:category => :children}, :conditions =>
['categories.user_id = ?', @user.id])

This does not seem to work. I'm only getting pictures that belong to
root categories. Can anyone tell me what I'm doing wrong? I have a
feeling that I'm thinking about this the wrong way somehow.

Thanks very much!
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2007-02-14 17:39
(Received via mailing list)
Carl Johnson wrote:
> I want to get all pictures that are members of a category that belong to
> a particular user and ALSO all pictures in children of those categories
> (one level of children is fine). I believe this is the correct syntax:
>
> Pictures.find(:all, :include => {:category => :children}, :conditions =>
> ['categories.user_id = ?', @user.id])
>
> This does not seem to work. I'm only getting pictures that belong to
> root categories. Can anyone tell me what I'm doing wrong? I have a
> feeling that I'm thinking about this the wrong way somehow.

I think you need something like:

Pictures.find :all, :include => {:category => :parent}, :conditions =>
<<-END
   categories.user_id = #{@user.id} or parent_categories.user_id =
#{@user.id}
END

--
We develop, watch us RoR, in numbers too big to ignore.
5e75f4b81923cd04a5c8fffa290be92e?d=identicon&s=25 Carl Johnson (carlivar)
on 2007-02-14 18:31
 > I think you need something like:
>
> Pictures.find :all, :include => {:category => :parent}, :conditions =>
> <<-END
>    categories.user_id = #{@user.id} or parent_categories.user_id =
> #{@user.id}
> END

You're right! That worked perfectly (though the condition is
parents_categories). Thank you!!

Now I need to try and understand the difference in the joins of
:children versus :parent. It seems a bit counter-intuitive to include
:parent when you want to make sure children are returned. I guess this
just means I am joining the parent_id field of children to their
parents, basically...?
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2007-02-15 00:47
(Received via mailing list)
Carl Johnson wrote:
> Now I need to try and understand the difference in the joins of
> :children versus :parent. It seems a bit counter-intuitive to include
> :parent when you want to make sure children are returned. I guess this
> just means I am joining the parent_id field of children to their
> parents, basically...?

The first level of category is that of the pictures being returned,
so you want to specify both the owners of these categories and
the owners of the categories for which these categories are child
categories -- that is owners of parent categories of these categories.

Using include gives you a neat query, but it's inefficient to
attach two layers of category models to each picture if they're
not being referenced in your code.

You can instead put the required joins explicitly in a :joins
parameter, but this makes the query look more complicated.

It'd be nice if one could write :joins => {:category => :parent}
and have Rails add the same joins and aliases as an :include,
but not do either field aliasing or selection and attachment of
the joined child models.

--
We develop, watch us RoR, in numbers too big to ignore.
This topic is locked and can not be replied to.