Spatie team recently released a new open source package called laravel-searchable
. This package simplifies the search between multiple models. In this article, we will implement this package to search blog post and events records.
I hope you have already done database connection for your project. Now, we will create two tables posts
and events
that will store articles and events records. We will create model and migration for this using following command:
// for posts php artisan make:model Post -m // for events php artisan make:model Event -m
This will create models and migrations for posts and events table. I will open the recently created migrations files and add the required fields. Thus, our posts
migraiton file looks like below:
Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->string('slug'); $table->text('body'); $table->string('submitted_by'); $table->string('published_by'); $table->string('status'); $table->string('image')->nullable(); $table->string('thumbnail')->nullable(); $table->timestamps(); });
Similarly, our events migration file looks like below:
Schema::create('events', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->string('slug'); $table->datetime('date'); $table->string('location'); $table->text('description'); $table->string('organizer')->nullable(); $table->string('status'); $table->string('image')->nullable(); $table->string('thumbnail')->nullable(); $table->timestamps(); });
So, To get started with the search function, let’s install the package first.
Install Package
We will install the package through composer. Run the following command:
composer require spatie/laravel-searchable
Create View
We need to create view file containing the input box for search function. We will also display the result in the same page. So, I have added extra code for displaying search results. Our final search blade looks like below:
@extends('frontend.layouts.default') @section('page_title', 'laravel Search in Multiple Model') @section('content')@endsection@if ( $searchResults-> isEmpty())Sorry, no results found for the term "{{ $searchterm }}".
@elseThere are {{ $searchResults->count() }} results for the term "{{ $searchterm }}"
@foreach($searchResults->groupByType() as $type => $modelSearchResults){{ ucwords($type) }}
@foreach($modelSearchResults as $searchResult) @endforeach @endforeach @endif
In this blade, I am extending a layout to give a nice overview. But, it’s not necessary to extend. You can either extends or simply display code between content section
between basic HTML boilerplate.
Route Setup
To view this blade, we need to add routes in our web.php file. I will add four routes.
// display records routes Route::get('events/{slug}', 'EventController@show')->name('events.show'); Route::get('posts/{slug}', 'NewsController@show')->name('posts.show'); // search routes Route::get('laravel-search-in-multiple-model', 'SearchController@index')->name('search.index'); Route::get('search', 'SearchController@search')->name('search.result');
If you get the EventsController not found.
error or NewsController not found.
error(s), you can create new respective controller.
Modify Models
We already created our Post
and Event
models. We need to implements Searchable
interface. Our Post
model will be as follow:
id); return new SearchResult( $this, $this->title, $url ); } }
Similarly, our Event
model looks like below:
id); return new SearchResult( $this, $this->title, $url ); } }
Be sure to import the interfaces at the top after namespace. We are using Spatie\Searchable\SearchResult
interface which implements getSearchResult()
method returning SearchResult
object. Don’t worry, this is just a PHP 7 syntax. If you want to know more about this, you can read New Features In PHP 7 – Explained.
Within that SearchResult() object we need to specify three parameters: where are we searching (model itself – $this), what is the returned column for title (it will be displayed in results – so category name, $this->name), and what URL the result should link to (we’re building that with route() helper)
The SearchResult()
method accepts 3 parameters i.e. the first one is model itself ($this), the second one column for a title that is returned and the last parameter is a route for displaying the specific record.
Controller
We will create a new controller that will process our search query. Simply run the below command to create one.
php artisan make:controller SearchController
Now, we will add two methods in this controller i.e. index
and search
. I have modify the controller file that looks like below:
input('query'); $searchResults = (new Search()) ->registerModel(Post::class, 'title') ->registerModel(Event::class, 'title') ->perform($request->input('query')); return view('frontend.search', compact('searchResults', 'searchterm')); } }
Now, it’s time to test the code. Before testing, I have seed the posts and events table. You can enter some random data for testing.


After running php artisan serve
, When we navigate to our route /laravel-search-in-multiple-model
, we will get the view as below.
Similarly, when we write something on the input field and hit enter, we get the results as below:
When no record is found, we get no record found message.
This is all for searching records in multiple models using laravel-searchable. If you have any query or feedback, don’t forget to drop a comment below.