Search code examples
laraveleloquenteloquent-relationship

hasOneThrough Laravel Eloquent Relationship


I have 3 tabes categories, sub_categories & products

  • category table
---------------------
| id | category_name |
---------------------
  • sub_category table
--------------------------------------------
| id | category_id(FK) | sub_category_name |
--------------------------------------------
  • product table
-----------------------------------------------------------------
| id | sub_category_id(FK) | product_name | product_description |
-----------------------------------------------------------------

**How do I get product category name using hasOneThrough eloquent relationship ( or using any other relationship). I tried this in product model **

public function category(){
return $this->hasOneThrough(
    Category::class, 
    SubCategory::class
);

}

But it gives error: Unknown column 'sub_categories.product_id'


Solution

  • You can install this external package staudenmeir/belongs-to-through to add the relationship you need.

    class Product extends Model
    {
        public function subCategory()
        {
            return $this->belongsTo(SubCategory::class);
        }
    
        public function category()
        {
            return $this->belongsToThrough(Category::class, SubCategory::class);
        }
    }
    
    class SubCategory extends Model
    {
        public function category()
        {
            return $this->belongsTo(Category::class);
        }
    }
    
    class Category extends Model
    {
        public function subCategories()
        {
            return $this->hasMany(SubCategory::class);
        }
    
        public function products()
        {
            return $this->hasManyThrough(Product::class, SubCategory::class);
        }
    }
    

    If you need to access Category directly from Product, and want to use laravels functions like $product->category()->attach($category->id) etc, then you need this dependency to achieve that.

    If you are ok with doing:

        $product->subCategory->category;
        // or
        $product->subCategory->category()->attach($category->id);
    

    Then you don't need the dependency and you can exclude the category relationship on the Product model.