Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

oka's avatar
Level 6

hasManyThrough relationship

Hi everyone.

Need advice on hasManyThrough relationship

I am using Laravel 5.4

I have three tables: Product, Sku, Stock


mysql> describe products;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255)     | NO   |     | NULL    |                |
| created_at | timestamp        | YES  |     | NULL    |                |
| updated_at | timestamp        | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
4 rows in set (0,00 sec)

mysql> describe skus;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| product_id | int(10) unsigned | NO   | MUL | NULL    |                |
| sku        | varchar(255)     | NO   | UNI | NULL    |                |
| price      | decimal(10,2)    | NO   |     | NULL    |                |
| created_at | timestamp        | YES  |     | NULL    |                |
| updated_at | timestamp        | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
6 rows in set (0,00 sec)

mysql> describe stocks;
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| warehouse_id | int(10) unsigned | NO   | MUL | NULL    |                |
| sku_id       | int(10) unsigned | NO   | MUL | NULL    |                |
| qty          | decimal(10,2)    | NO   |     | NULL    |                |
| created_at   | timestamp        | YES  |     | NULL    |                |
| updated_at   | timestamp        | YES  |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+

On Product Model:


public function stock(){
        return $this->hasManyThrough('App\Stock', 'App\Sku');
    }

On Stock Model:


public function product(){
        return $this->hasManyThrough('App\Product', 'App\Sku', 'product_id', 'id', 'sku_id');
    }

I am able to query Product Model with Stock:


$ App\Product::with(['stock'])->get()

=> Illuminate\Database\Eloquent\Collection {#681
     all: [
       App\Product {#669
         id: 1,
         name: "Product-1",
         stock: Illuminate\Database\Eloquent\Collection {#696
           all: [
             App\Stock {#698
               id: 1,
               warehouse_id: 1,
               sku_id: 1,
               qty: "555.00",
               product_id: 1,
             },
             App\Stock {#699
               id: 6,
               warehouse_id: 2,
               sku_id: 3,
               qty: "69.00",
               product_id: 1,
             },
           ],
         },
       },
       App\Product {#690
         id: 2,
         name: "Product-2",
         stock: Illuminate\Database\Eloquent\Collection {#667
           all: [
             App\Stock {#702
               id: 5,
               warehouse_id: 2,
               sku_id: 2,
               qty: "233.00",
               product_id: 2,
             },
           ],
         },
       },
     ],
   }

The problem is when querying Stock Model with Products I get empty product collection results only with the last two records (first record is populated with product):


$ App\Stock::with(['product'])->get();

=> Illuminate\Database\Eloquent\Collection {#679
     all: [
       App\Stock {#676
         id: 1,
         warehouse_id: 1,
         sku_id: 1,
         qty: "555.00",
         product: Illuminate\Database\Eloquent\Collection {#694
           all: [
             App\Product {#709
               id: 1,
               name: "Product-1",
               product_id: 1,
             },
           ],
         },
       },
       App\Stock {#675
         id: 5,
         warehouse_id: 2,
         sku_id: 2,
         qty: "233.00",
         product: Illuminate\Database\Eloquent\Collection {#700
           all: [],
         },
       },
       App\Stock {#695
         id: 6,
         warehouse_id: 2,
         sku_id: 3,
         qty: "69.00",
         product: Illuminate\Database\Eloquent\Collection {#692
           all: [],
         },
       },
     ],
   }

Thanks for reading.

0 likes
1 reply
oka's avatar
Level 6

Solved

I can get product model through Sku model.

$ App\Stock::with(['sku.product'])->get();

Regards.

Please or to participate in this conversation.