理解 sole() 查詢構造器方法

laradocs發表於2021-09-26

原文:Understanding the sole() Query Builder Method

目錄

前言

Laravel 8.23 在查詢構造器上引入了一個 sole() 方法,它檢索單個記錄,但也具有附加斷言。

你需要查詢單行並且斷言查詢僅匹配一條記錄時,Sole 很有用。你期望只要一條記錄時,這很有幫助。當存在多條或沒有記錄時,Laravel 會丟擲異常。

我們會演示使用它以及從三種可能的場景中得到什麼:

  1. 一條和查詢匹配的記錄
  2. 沒有和查詢匹配的記錄
  3. 多條和查詢匹配的記錄

快速開始

讓我們建立一個快速演示應用程式,以便你可以根據需要繼續進行實驗。
首先,建立一個 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 協議》,轉載必須註明作者和本文連結
站在巨人的肩上

相關文章