原文:Understanding the sole() Query Builder Method
目錄
前言
Laravel 8.23 在查詢構造器上引入了一個 sole() 方法,它檢索單個記錄,但也具有附加斷言。
你需要查詢單行並且斷言查詢僅匹配一條記錄時,Sole 很有用。你期望只要一條記錄時,這很有幫助。當存在多條或沒有記錄時,Laravel 會丟擲異常。
我們會演示使用它以及從三種可能的場景中得到什麼:
- 一條和查詢匹配的記錄
- 沒有和查詢匹配的記錄
- 多條和查詢匹配的記錄
快速開始
讓我們建立一個快速演示應用程式,以便你可以根據需要繼續進行實驗。
首先,建立一個 Laravel 專案:
laravel new sole-demo
cd sole-demo
接下來,建立一個模型,我們可以用來演示 sole() 是如何工作的:
php artisan make:model -m Book
最後,我們將為我們的模型定義 book 資料庫表:
database/migrations/xxxx_xx_xx_xxxxxx_create_books_table.php
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('books', 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('books');
}
}
不要忘記確保我們建立的欄位是可寫入的:
app/Models/Book.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var string[]
*/
public $fillable = [
'title',
'summary'
];
}
執行遷移檔案:
php artisan migrate:fresh
您現在應該有一個 books 表了,我們將用它來演示一些示例。
使用 sole() 方法
為了實驗 sole(),我們將使用 php artisan tinker
命令來建立記錄並查詢資料庫。
首先,讓我們看看當我們使用 first() 和 get() 方法會發生什麼。
use App\Models\Book;
Book::create ( [
'title' => 'War of the Worlds',
'summary' => 'Example summary' ,
] );
// 所有匹配查詢的記錄
Book::where ( 'title', 'like', '%War%' )->get();
/**
Illuminate\Database\Eloquent\Collection {#4264
all: [
App\Models\Book {#4209
id: 1,
title: "War of the Worlds",
summary: "Example summary",
published_at: null,
created_at: "2021-09-26 18:14:29",
updated_at: "2021-01-21 18:14:29",
},
],
}
*/
// 獲取查詢的第一條記錄
// 即使查詢有多條匹配項,也返回第一條
Book::where ( 'title', 'like', '%War%' )->first();
/**
App\Models\Book {#4210
id: 1,
title: "War of the Worlds",
summary: "Example summary",
published_at: null,
created_at: "2021-09-26 18:14:29",
updated_at: "2021-09-26 18:14:29",
}
*/
get()
和 first()
方法在 Laravel 中相當常見,但是,當你期望只有一條記錄存在時,sole() 很有用:
/**
App\Models\Book {#3647
id: 1,
title: "War of the Worlds",
summary: "Example summary",
published_at: null,
created_at: "2021-09-26 18:14:29",
updated_at: "2021-09-26 18:14:29",
}
*/
如果在資料庫表中沒有記錄,我們可以預期丟擲 ModelNotFoundException
:
Book::where('title', 'like', '%The War')->sole();
// Illuminate\Database\Eloquent\ModelNotFoundException
如果在資料庫表中有多條記錄,我們也會得到一個異常,但這次是 MultipleRecordsFoundException
:
// 建立第二個 title,其中包含 `War` 一詞。
Book::create ( [
'title' => 'War and Peace',
'summary' => 'Example summary',
] );
Book::where ( 'title', 'like', '%War%' )->sole();
// Illuminate\Database\MultipleRecordsFoundException
本作品採用《CC 協議》,轉載必須註明作者和本文連結