We can easily search single model data using Laravel scout. But it is a bit difficult to search multiple models or relationship data using Laravel scout. In this example, I will show you laravel scout search multiple models using a database driver.

I will use the category and post model to create this search functionality. I will make a belongs to a relationship with the product with a category which means a product only has one category. Then we will search for products according to category.

Let's see the preview image and html form demo output of how to search relationship data with laravel scout.

laravel-scout-full-text-search-with-relationship-example

Step 1: Install Laravel 10

First of all, we need to get a fresh Laravel 10 version application using the bellow command, So open your terminal OR command prompt and run the bellow command to start laravel scout search relationship.

composer create-project laravel/laravel example-app

 

Step 2: Connect Database

After successfully installing the laravel app and then configuring the database setup. We will open the ".env" file and change the database name, username, and password in the env file to create laravel scout eager loading.

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=Enter_Your_Database_Name
DB_USERNAME=Enter_Your_Database_Username
DB_PASSWORD=Enter_Your_Database_Password

 

Read also: Laravel 10 New Feature - Laravel Pennant Overview

 

Step 3: Create Migration and Model

In this step, we need to create posts and categories table and model. then we need to run a migration. so let's change the files.

php artisan make:model Product -m
php artisan make:model Category -m

 

Now update the migration like below:

database/migrations

<?php

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

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

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

 

And migrations for products table:

<?php

use App\Models\Category;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->foreignIdFor(Category::class);
            $table->string('name');
            $table->timestamps();
        });
    }

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

 

And now update the model like the below:

app/Models/Product.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Product extends Model
{
    use
        HasFactory,
        Searchable;

    protected $guarded = [];

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function toSearchableArray()
    {
        return [
            'name' => '',
            'categories.name' => '',
        ];
    }
}

 

Now update the category model like:

app/Models/Category.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use HasFactory;

    protected $guarded = [];
}

 

Step 4: Generate Seeder

We need dummy data for the product and category table. So create a seeder like:

php artisan make:seeder ProductSeeder
php artisan make:seeder CategorySeeder

 

Now update the product seeder like:

Database\Seeders\ProductSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Category;
use App\Models\Product;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        for ($i = 0; $i < 20; $i++) {
            Product::create([
                'category_id' => random_int(1, 9),
                'name'        => fake()->paragraph()
            ]);
        }
    }
}

 

Now update the category seeder like:

Database\Seeders\CategorySeeder.php

<?php

namespace Database\Seeders;

use App\Models\Category;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class CategorySeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        for ($i = 0; $i < 10; $i++) {
            Category::create([
                'name' => fake()->name()
            ]);
        }
    }
}

 

Now update the database seeder file like:

Database\Seeders\DatabaseSeeder.php

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;

use App\Models\Employee;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        $this->call(ProductSeeder::class);
        $this->call(CategorySeeder::class);
    }
}

 

Now run the migration command:

php artisan migrate

//and

php artisan db:seed

 

Step 5: Create Route

Here, we need to add one route to display the products data and make a search functionality in laravel 10 using scout with related data. So add it like the below:

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SearchController;

Route::get('product', [SearchController::class, 'index'])
    ->name('product.search');

 

Step 6: Create Controller

Here, we need to add the index() method for fetching product data for creating an advanced full text search in laravel using scout with multiple models.

app/Http/Controllers/TutorialController.php

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class SearchController extends Controller
{
    public function index(Request $request)
    {
        $products = Product::search(
            trim($request->get('search')) ?? ''
        )
            ->query(function ($query) {
                $query->join('categories', 'products.category_id', 'categories.id')
                    ->select(['products.id', 'products.name', 'categories.name as category'])
                    ->orderBy('products.id', 'DESC');
            })
            ->paginate(5);

        return view('product.index', compact('products', 'request'));
    }
}

 

Step 7: Install And Setup Scout

In this step, we will use scout to search for data from the model. Scout has a composer package and command. So install it by the below command:

composer require laravel/scout

 

Next, we may publish the configuration file like this:

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

 

Now we have to set the database as a driver in your env file for laravel scout search example:

.env

SCOUT_DRIVER=database

 

Now run the below command to import data for searching:

php artisan scout:import "App\Models\Product"

 

Now if you run this command, you will see the below output:

Imported [App\Models\User] models up to ID: 20
All [App\Models\Product] records have been imported.

 

Step 8: Create Blade file

In this step, we need to create a welcome blade file and update the file. so let's change it.

resources/views/product/index.blade.php

@extends('layouts.app')

@section('content')
    <div class="panel panel-default">
        <div class="panel-body">
            <form action="{{ route('product.search') }}" method="get">
                 <div class="row">
                    <div class="col-md-10 form-group">
                        <label for="">Category</label>
                        <input type="text" name="search" class="form-control">
                     </div>
                     <div class="col-md-2 form-group" style="margin-top:25px;">
                        <input type="submit" class="btn btn-primary" value="Filter">
                     </div>
                 </div>
            </form>
            <strong>Product List</strong>
            <table class="table table-responsive table-bordered table-stripped" style="margin-top:10px;">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Name</th>
                        <th>Category</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($products as $product)
                    <tr>
                        <td>{{ $product->id }}</td>
                        <td>{{ $product->name }}</td>
                        <td>{{ $product->category }}</td>
                    </tr>
                    @endforeach
                </tbody>
            </table>
            {{ $products->links() }}
        </div>
    </div>
@endsection

 

Ok, now we are ready to go and test laravel scout eager loading search example.

php artisan serve

 

Now you can test our application by visiting the below URL:

URL
http://127.0.0.1:8000/product

 

Read also: Laravel 10 Multi Select Dropdown Filter Example

 

Conclusion

Now we know laravel scout search multiple models. Hope this laravel scout search relationship tutorial will help you to laravel scout eager loading search example.

Category : #laravel

Tags : #laravel , #laravel search