Note that there are some explanatory texts on larger screens.

plurals
  1. PORuby on Rails Pattern for Collecting has_many Objects in a Tree of Nodes
    primarykey
    data
    text
    <p>I have an organizational hierarchy represented via <a href="https://github.com/collectiveidea/awesome_nested_set/" rel="nofollow">awesome nested set</a> on a Node model. Great, works great, the updates are expensive but the finds are super efficient. </p> <p>Each Node model has_many on other models, let's call them Foo and Bar. </p> <pre><code>class Node &lt; ActiveRecord::Base acts_as_nested_set has_many :foos has_many :bars end class Foo &lt; ActiveRecord::Base belongs_to :node end </code></pre> <p>Frequently, I want to find all of the foos or bars for a given subtree, looking down from a current node. Naively, I could do:</p> <pre><code>@foos = @node.self_and_descendants.collect(&amp;:foos).compact </code></pre> <p>I could even use an ActiveRecord .includes(:foos) to avoid N+1 queries. What I really want is just to ask for <code>@node.all_foos</code> so I implement something like this: </p> <pre><code>class Node &lt; ActiveRecord::Base def all_foos Foo.where(node_id: self_and_descendants.pluck(:id)) end # More efficient? def all_foos_alternately Foo.where(node_id: self_and_descendants.includes(:foos).pluck(:id)) end end </code></pre> <p>But, let's say that I want to “collect” more than just foos and bars, let's say that I have half a dozen or a dozen of this models. Now I'm littering my Node class or some lib with a bunch of all_* methods. </p> <p>Should I be defining class methods on the foos and bars that accept a node as an argument and return all of the foos/bars for that subtree? But then the foos and bars need to understand/be aware of node.self_and_descendants. </p> <p>Or the Foo class method could accept a collection of nodes, not needing to be aware of the nested set methods, but then I lose the easy interface via <code>node.all_foos</code> or the like. </p> <p>What's the pattern or method I'm missing here? I've played with implementing a catch-all for <code>node.all_*</code> via method_missing but don't like the performance hit. What I'm trying to execute here is, at its core, a database lookup and, as such, it should be efficient and elegant. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload