Updated 15 May 2023
With the release of Laravel 8.23, ‘sole()’ method in laravel query builder is introduced, which retrieves a single record but has additional assertions.
Sole is beneficial once you need one row from the query and assert the query only matches one record. It’s advantageous once you expect one record but want absolute assurance that only one record exists. When quite one or but one record exist, Laravel throws an exception.
In order to make it more clear, Let’s check it out how we can use sole() method in different scenarios.
Let’s take 3 different scenarios here:
First let’s create a Laravel App app:
1 |
laravel new bagisto |
Now we need to create a Model:
1 |
php artisan make:model -m bagisto |
Now we need to Bagisto database table for our model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateBooksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('bagisto', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('summary'); $table->dateTime('published_at')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('bagisto'); } } |
Now Run the Migrate command:
1 |
php artisan migrate:fresh |
To experiment with sole(), we’ll use the php artisan tinker command to make records and query the database. First up, let’s see what happens once we use the standard first() or get() methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
use App\Models\Bagisto; Book::create([ 'title' => 'Bagisto', 'summary' => 'Laravel Ecommerce' ]); // All the records that match the query Book::where('title', 'like', '%War%')->get(); Illuminate\Database\Eloquent\Collection {#4264 all: [ App\Models\Book {#4209 id: 1, title: "Bagisto", summary: "Laravel Ecommerce", published_at: null, created_at: "2021-01-21 22:14:29", updated_at: "2021-01-21 22:14:29", }, ], } // Get the first record in the query // Even if the query has multiple matches, return the first one Book::where('title', 'like', '%War%')->first(); => App\Models\Book {#4210 id: 1, title: "bagisto", summary: "Laravel Ecommerce", published_at: null, created_at: "2021-01-21 22:14:29", updated_at: "2021-01-21 22:14:29", } |
The get() and first() methods are fairly common in Laravel apps, however, sole() is beneficial once you expect and need to ensure the existence of 1 and just one record:
1 2 3 4 5 6 7 8 9 10 |
Book::where('title', 'like', '%War%')->sole(); App\Models\Book {#3647 id: 1, title: "War of the Worlds", summary: "Example summary", published_at: null, created_at: "2021-01-21 22:14:29", updated_at: "2021-01-21 22:14:29", } |
If we don’t have a record within the database table, we will expect the ModelNotFoundException thrown:
1 2 |
Book::where('title', 'like', '%The War')->sole(); // => Illuminate\Database\Eloquent\ModelNotFoundException |
If we’ve quite one record within the database table, we also get an exception, but this point it’s the MultipleRecordsFoundException:
1 2 3 4 5 6 7 |
// Create a second title with the word `War` in it. Book::create([ 'title' => 'War and Peace', 'summary' => 'Example summary' ]); Book::where('title', 'like', '%War%')->sole(); // => Illuminate\Database\MultipleRecordsFoundException |
Sources:
Laravel’s Site
Laravel News
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.