title: Laravel: Querying and accessing child objects in nested relationship with where clauses
body: <p>I am trying to access the child objects of nested relationships that return many results from the parents object.  </p>
  
  <p>Let's say I have 4 models : Country - Provinces - Cities - Municipalities</p>
  
  <p>Their relationships are as follows : </p>
  
  <p><strong>Country Model</strong></p>
  
  <pre><code>class Country extends Eloquent
  {
     protected $table = 'countries';
  
     public function provinces()
     {
         return $this-&gt;hasMany('Province');
     }
  }
  </code></pre>
  
  <p><strong>Province Model</strong></p>
  
  <pre><code>class Province extends Eloquent
  {
     protected $table = 'provinces';
  
     public function cities()
     {
         return $this-&gt;hasMany('City');
     }
     public function country()
     {
         return $this-&gt;belongsTo('Country');
     }
  }
  </code></pre>
  
  <p><strong>City Model</strong></p>
  
  <pre><code>class City extends Eloquent
  {
     protected $table = 'cities';
  
     public function municipalities()
     {
         return $this-&gt;hasMany('Municipality');
     }
     public function province()
     {
         return $this-&gt;belongsTo('Province');
     }
  }
  </code></pre>
  
  <p><strong>Municipality Model</strong></p>
  
  <pre><code>class Municipality extends Eloquent
  {
     protected $table = 'municipalities';
  
     public function cities()
     {
        return $this-&gt;belongsTo('City');
     }
   }
  </code></pre>
  
  <p>Now what I am trying to do is get all municipalities in a given country that have a population over 9000 and are located in provinces that are considered West.</p>
  
  <p>So far I have something like this : </p>
  
  <pre><code>   $country_id = 1;
  
     $country = Country::whereHas('provinces', function($query){
          $query-&gt;where('location', 'West');
          $query-&gt;whereHas('cities', function($query){ 
              $query-&gt;whereHas('municipalities', function($query){
                  $query-&gt;where('population', '&gt;', 9000);
              });            
          });
      })-&gt;find($country_id); 
  </code></pre>
  
  <p>Now I can easily get the provinces with <code>$country-&gt;provinces</code> but I can't go any deeper than that.</p>
  
  <p>EDIT1 : Fixing the belongsTo relationship as noticed by Jarek.</p>
  
  <p>EDIT2: In addition to Jarek's answer, I wanted to share what I also found however Jarek's is probably the more proper method.</p>
  
  <p>Instead of trying to go from top to bottom (Country -> Municipality) I decided to try the other way (Municipality -> Country) Here's how it works (and I tested it, also works)</p>
  
  <pre><code>          $municipalities = Municipality::where('population', '&gt;', 9000)
              -&gt;whereHas('city', function($q) use ($country_id){
                  $q-&gt;whereHas('province', function($q) use ($country_id){
                      $q-&gt;where('location', 'West');
                      $q-&gt;whereHas('country', function($q) use ($country_id){
                            $q-&gt;where('id', $country_id);
                      });
                  });
              })-&gt;get();
  </code></pre>
  
  <p>I have no idea if this is an actual proper way or if performance would be accepted but it seemed to do the trick for me however Jarek's answer looks more elegant.</p>