title: Laravel Recursive Relationships
body: <p>I'm working on a project in <em>Laravel</em>. I have an Account model that can have a parent or can have children, so I have my model set up like so:</p>
  
  <pre><code>public function immediateChildAccounts()
  {
      return $this-&gt;hasMany('Account', 'act_parent', 'act_id');
  }
  
  public function parentAccount()
  {
      return $this-&gt;belongsTo('Account', 'act_parent', 'act_id');
  }
  </code></pre>
  
  <p>This works fine. What I want to do is get all children under a certain account. Currently, I'm doing this:</p>
  
  <pre><code>public function allChildAccounts()
  {
      $childAccounts = $this-&gt;immediateChildAccounts;
      if (empty($childAccounts))
          return $childAccounts;
  
      foreach ($childAccounts as $child)
      {
          $child-&gt;load('immediateChildAccounts');
          $childAccounts = $childAccounts-&gt;merge($child-&gt;allChildAccounts());
      }
  
      return $childAccounts;
  }
  </code></pre>
  
  <p>This also works, but I have to worry if it's slow. This project is the re-write of an old project we use at work. We will have several thousand accounts that we migrate over to this new project. For the few test accounts I have, this method poses no performance issues.</p>
  
  <p>Is there a better solution? Should I just run a raw query? Does <em>Laravel</em> have something to handle this? </p>
  
  <p><strong>In summary</strong>
  What I want to do, for any given account, is get every single child account and every child of it's children and so on in a single list/collection. A diagram:</p>
  
  <pre><code>A -&gt; B -&gt; D
  |--&gt; C -&gt; E
       |--&gt; F 
  G -&gt; H
  </code></pre>
  
  <p>If I run A->immediateChildAccounts(), I should get {B, C}<br>
  If I run A->allChildAccounts(), I should get {B, D, C, E, F} (order doesn't matter)</p>
  
  <p>Again, my method works, but it seems like I'm doing way too many queries.</p>
  
  <p>Also, I'm not sure if it's okay to ask this here, but it is related. How can I get a list of all accounts that <strong>don't</strong> include the child accounts? So basically the inverse of that method above. This is so a user doesn't try to give an account a parent that's already it's child. Using the diagram from above, I want (in pseudocode):</p>
  
  <p>Account::where(account_id not in (A->allChildAccounts())). So I would get {G, H}</p>
  
  <p>Thanks for any insight.</p>