I have a model Tag, which is a tree model (using closure_tree
) and thanks to the gem I can do stuff like:
Tag.includes(:children).first
to eager load its children. Now, I have an instance method, which also uses children. So when I get a tag by the mentioned query, iterate over the tag and its children and call this instance method, the bullet
gem complains that I am doing a N+1 queries and advises me to include(children)
. This happens because I have not loaded the children of the children, so when calling the instance method, I make a separate query for the children of each sub-tag of the first-level tag.
I can solve this by doing the following:
Tag.includes(children: :children).first
In this case ActiveRecord eagerly loads the tag, its children and the children of its children. This, however, works if there are only 3 generations - the tag is a grandparent and then come the parents (which are children of the root tag) and the grandchildren (which are the children of the children of the root tag). If I have, say, 4 generations, than I must do:
Tag.includes(children: {children: :children}).first
So if I can determine the depth
of the farthest grand child of a root tag, is there a way to conditionally construct my query - if depth is 2, use includes(:children)
, if depth is 3 - use includes(children: :children)
and so on?
Judging from the documentation at: https://github.com/mceachen/closure_tree#usage you should use
This will retrieves all the children, sub-children, etc.. until it ends on a leaf.