Laravel hasManyThrough Eloquent Example Retrieve Records

Laravel One To Many Relationship, laravel many to many relationship, laravel hasmanythrough, laravel one to many polymorphic, laravel one to one polymorphic, Laravel Many To Many Polymorphic Tutorial Example, laravel hasonethrough, Laravel PDF Generator

Read about Laravel hasManyThrough Eloquent Example.

Laravel has several types of eloquent relationships by default. Such as one to one, one to many, many to many etc.

This various eloquent relationships helps developers to write efficient code in less time.

Laravel hasManyThrough Eloquent Relationship

Laravel hasManyThrough Eloquent relationship takes place among three tables of database.

Upper level table has relationship with many rows of middle level table and middle level table has relationship with many rows of lower level table.

For example, upper level table is shops , middle level table is products and lower level table is orders.

Any shop can have many types of products (electronic, furniture etc). Similarly, products can have more than of one type of order (single order, bulk order etc).

Now, with the use of hasManyThrough() function, we can fetch the records of lower level table orders with model of upper level table shops.

See the below image for live example.

Laravel hasManyThrough

shops have many products and products have many orders.

Now if you wish to get rows of orders table using Shop model, hasManyThrough relationship will help us for this.

Let us see how we can use above tables in live laravel project but before that take a look at the below video, which is the final output of our example.

 

Step 1. Fresh new project and database

First of all, run the following command

laravel new laramanythrough

Now, go to your database administration tool. I am using sequel pro for macbook. If you are using phpMyAdmin or any other, than it also compatible.

In your database tool, make a new database and give it a name like “laramanythrough

Now we need to connect this database with our laravel project.

For that, open your editor and navigate to .env file.

You need to update below lines in your .env file.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laramanythrough
DB_USERNAME=root
DB_PASSWORD=

Update database name, username etc. above fields as per your computer configuration.

Now both our new laravel project and database have connected with each other.

Step 2. Creating Three Tables

We need to make three tables ( upper, middle and lower ) in database.

So first of all, run the below command

php artisan make:migration create_shops_table

Then, run the following command

php artisan make:migration create_products_table

Finally, trigger the below command

php artisan make:migration create_orders_table

Above three commands will create three tables like shops, products and orders respectively.

Now, Go to database->migrations directory and open timestamp_create_shops_table.php file.

Add the following source snippet in timestamp_create_shops_table.php file.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateShopsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('shops', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('shop_name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('shops');
    }
}

up() function in above code includes column names for shops table.

Now write down the below code in timestamp_create_products_table.php file.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('products_name');
            $table->bigInteger('shop_id')->unsigned()->index();
            $table->timestamps();
            $table->foreign('shop_id')->references('id')->on('shops')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Column names of products table are included in the up() method of above code.

It has shop_id as the foreign key. This foreign is referencing the id field of shops table.

Now open the timestamp_create_orders_table.php file and write the following source snippet in it.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateOrdersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string("order_name");
            $table->bigInteger('product_id')->unsigned()->index();
            $table->timestamps();
            $table->foreign('product_id')->references('id')->on('products')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('orders');
    }
}

This order table migration file uses product_id as the foreign key and it is representing id from the products table.

After setting up all three migrations file, run the following command

php artisan migrate

Now check your database. You should see all the tables.

Step 3. Writing Models

We need to create three model file in this example.

So, run the below command in terminal

php artisan make:model Shop

Then, go for below command

php artisan make:model Product

At last, trigger the following one

php artisan make:model Order

So, these three commands will create Shop.php , Product.php and Order.php model files respectively.

Here, we do not need to add anything in two models : Order.php and Product.php

Source code for Order.php is as the below

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    //
}

Product.php should have the following code snippet

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    //
}

So no need to do anything in above two files.

We will add main logic in Shop.php file. Below is the main source code for Shop.php file.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Shop extends Model
{
    //
    public function orders()
    {
        return $this->hasManyThrough(
            Order::class,
            Product::class,
            'shop_id', // Foreign key on products table...
            'product_id', // Foreign key on orders table...
            'id', // Local key on countries table...
            'id' // Local key on users table...
        );
    }
}

This file uses hasManyThrough() function to define this relationship.

First parameter is the table from which we want to fetch records. For this record, we will use products table as a mediator.

Step 4. Filling Database

Let us manually add some rows in all three database tables.

Take a look at the following image

Laravel hasManyThrough

As per the image, add three rows in all three tables with values as per the above image.

Step 5. Controller and Route Tasks

Go to routes->web.php file and add the below source line in it

Route::get('manythrough','ShopsController@shopOrder');

It is defining one route. When the user visits “http://127.0.0.1:8000/manythrough” link in his browser, compiler will run this route.

Compiler will run the shopOrder() function from ShopsController.php file.

For making ShopsController.php file, run the following command

php artisan make:controller ShopsController

After this command, you will see that under app->Http->Controllers directory, your controller file has generated by the compiler.

Now write down the below source snippet in ShopsController.php file

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Shop;
use App\Order;

class ShopsController extends Controller
{
    //
    public function shopOrder()
    {
 
        $shops = Shop::find(1);	
        $shopOrders = $shops->orders;

        $shops = Shop::find(2);	
        $shopOrdersTwo = $shops->orders;

        $shops = Shop::find(3);	
        $shopOrdersThree = $shops->orders;

        //dd($shops->orders);
     
        return view('index',compact('shopOrders','shopOrdersTwo','shopOrdersThree'));
       
    }
}

First line in the above snippet will give us the rows from the orders table. See that we are using Shop model for fetching records from orders table.

This line will fetch the rows where the value of id is 1 in shops table. Now question arise, there is no reference between shops and orders table then how we can do this ? For this see the below image

Laravel hasManyThrough

 

shops and orders have reference between each other via products table. orders table have product_id which referring id from products table. Now, products table have shop_id which is referring id from shops table.

You can see that orders table have 1,2 and 3 values as product_id. Now, check products table, among 1,2 and 3 values of id, 1 and 2 have value 1 as a shop_id.

Thus, a line $shop = Shop::find(1) will return first two rows from orders table.

Similarly, we will get the rows from orders table for shop_id 2 and 3.

At last, compiler will give one return statement, which will open the index.blade.php view file. Along with this file, it will send variables as a parameter.

Step 6. Last step of view file

Navigate to resources->views directory and make a new file index.blade.php

You need to add following source code in index.blade.php

<html>
<head>
   
</head>
<style>
 
 
</style>
 
<h1> Laravel  hasManyThrough Example </h1>
 
<h3> All Orders for India Shop </h3>
 
@foreach ($shopOrders as $order)
<li> 
 
    {{ $order->order_name }}  
 
</li>
@endforeach

<h3> All Orders for USA Shop </h3>

@foreach ($shopOrdersTwo as $order)
<li> 
 
    {{ $order->order_name }}  
 
</li>
@endforeach

<h3> All Orders for UK Shop </h3>

@foreach ($shopOrdersThree as $order)
<li> 
 
    {{ $order->order_name }}  
 
</li>
@endforeach


</html>

In this file, we will display all the records, that we have fetched from the orders table.

For this, we will use those variables which we have written in the return statement in the controller function.

Download Source Code For Laravel hasManyThrough

Visit here for full source code