Eloquent hasManyThrough: jumping deeper into relationships

Quite often in bigger projects there are DB relationships with more than one level: categories->companies->products, countries->teams->players and similar. If we need to get the list of a deeper level, there's a quick way of doing that with Eloquent. Let's take one of the examples above: product categories, each with companies, each company with products. What if we want to get the list of products by category? Simplified DB structure: categories - id - name companies - id - category_id - name products - id - company_id - name So, in our Category model we should probably have companies() with hasMany('App\Company') relationship, and in the model Company there should be products() method with another hasMany('App\Product') relationship. That's fine, but let's go a level deeper - meet function hasManyThrough().
class Category extends Model
{
    /**
     * Get all of the products for the category.
     */
    public function products()
    {
        return $this->hasManyThrough('App\Product', 'App\Company');
    }
}
Now, if in the code you call $category->products - you will have a perfectly valid list of Product instances. Please notice the order of parameters - first parameter is the final deepest third-level class, and then comes the middle-part class. Another quick tip - if you need to specify columns for the relationships, you can do that by adding more parameters at the end:
public function products()
{
  return $this->hasManyThrough('App\Product', 'App\Company',
    'category_id', 'company_id');
}

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 58 courses (1054 lessons, total 46 h 42 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials