Laravel 模型使用全局作用域和局部作用域

一. 需要解決什么問題

最近Laravel 項目中遇到一個需求,我有一個客戶表,每個員工都有自己的客戶,但是自己只能看自己的客戶。

項目中,有很多功能需要查詢客戶列表,客戶詳情,查詢客戶入口很多,這些查詢出來的數據,無一例外都只能查自己的。

問題來了,每個查詢點都去補充限制條件,處理起來非常繁瑣,而且維護成本很高容易出現問題,一旦出現條件不到位,就可能造成不可估量的損失。

類似以上這種需求,應該有很多相似的。大家自覺往上靠。

提出疑問,可有辦法統一處理,只維護一處即可,所有查詢都帶上條件限制。

答案肯定是有,以下是其中一個解決思路,也是推薦的。

二. 什么是查詢作用域

查詢作用域(Query Scope)是 Laravel Eloquent ORM 提供的一個強大功能,它允許你封裝常用的查詢邏輯,使代碼更簡潔、可重用。合理使用可以大幅提高代碼質量和開發效率。

在這里插入圖片描述

三. 作用域怎么用

3.1 全局作用域

全局作用域可以為模型的所有查詢添加約束。最常見的 軟刪除 功能就是利用全局范圍僅從數據庫中檢索「未刪除」模型。

3.1.1 開發全局作用域

編寫作用域類,目錄可以是任意目錄,我創建在 App\Models\Scopes 下面

<?phpnamespace App\Models\Scopes;use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;class ClientScope implements Scope
{public function apply(Builder $builder, Model $model): void{$builder->where('uid_code', '=', get_admin_code());}
}

代碼解釋:

  1. 需要實現 Illuminate\Database\Eloquent\Scope 接口
  2. Scope 接口要求實現 apply 方法。需要完善 apply 方法
  3. apply 方法里面補充的就是所需要的限制條件,例如我的就是指定 uid_code 等于 當前登錄用戶code

在需要模型里面,配置全局作用域

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Scopes\ClientScope;
use Illuminate\Database\Eloquent\Factories\HasFactory;class ClientModel extends Model
{use HasFactory;protected static function booted(): void{static::addGlobalScope(new ClientScope());}
}

代碼解釋:

  1. 重寫模型的 booted 方法并使用 addGlobalScope 方法
  2. addGlobalScope 方法可以接受作用域的一個實例參數,也就是上面編寫的作用域

完成上面的步驟即可,在使用 ClientModel 模型查詢時,都會帶上作用域里面的條件。

3.1.2 匿名全局作用域

是不是感覺上面的代碼繁瑣了,為了一個全局作用域還需要單獨去編寫一個類。那么使用閉包來定義全局作用域,可以簡化流程。

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;class ClientModel extends Model
{use HasFactory;protected static function booted(): void{static::addGlobalScope('clientScope', function (Builder $builder) {$builder->where('uid_code', '=', get_admin_code());});}
}

代碼解釋:

  1. 重寫模型的 booted 方法并使用 addGlobalScope 方法
  2. addGlobalScope 方法,第一個參數為作用域名稱第二個參數為匿名函數,里面補充就是相關條件。

注意

匿名全局作用域適用于單獨模型使用,如果有多個模型,都需要同樣的限制條件,則還是需要創建作用域類的。方便統一維護。視情況而定

3.1.3 取消全局作用域

如果某個查詢不需要這個全局限制,那么就可以取消全局作用域

  1. 取消部分,或者指定作用域
//取消全局作用域類
ClientModel::withoutGlobalScope(ClientScope::class)->get();
//取消閉包作用域
ClientModel::withoutGlobalScope('clientScope')->get();
// 取消部分作用域...
ClientModel::withoutGlobalScopes([ClientScope::class, SecondScope::class
])->get();
  1. 取消全部作用域
// 取消全部全局作用域...
ClientModel::withoutGlobalScopes()->get();

3.2 局部作用域

局部作用域允許你定義通用的查詢約束,可以鏈式調用

// 在模型中定義
class ClientModel extends Model
{public function scopePopular($query){return $query->where('votes', '>', 100);}public function scopeActive($query){return $query->where('active', 1);}
}

使用方法:

// 單個作用域
$users = ClientModel::popular()->get();// 鏈式調用多個作用域
$users = ClientModel::popular()->active()->orderBy('created_at')->get();//使用orWhere實現
$users = ClientModel::popular()->orWhere->active()->get();//使用閉包實現
$users = ClientModel::popular()->orWhere(function (Builder $query) {$query->active();
})->get();

3.3 動態作用域

動態作用域允許你傳遞參數給作用域:

// 定義
class ClientModel extends Model
{public function scopeOfType($query, $type){return $query->where('type', $type);}
}

注意:作用域參數要放在 $query 參數之后

// 使用
$users = ClientModel::ofType('admin')->get();

四. 總結

查詢作用域是 Laravel Eloquent 中組織查詢邏輯的強大工具,合理使用可以大幅提高代碼質量和開發效率。

合理使用 全局作用域和局部作用域,可以使查詢邏輯更清晰易懂,方便維護,降低后期的查看查看成本。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78694.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78694.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78694.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Nova UI】十二、打造組件庫之按鈕組件(上):邁向功能構建的關鍵一步

序言 在上一篇文章中&#xff0c;我們深入探索了 icon 組件從測試到全局注冊的全過程&#x1f3af;&#xff0c;成功為其在項目中穩定運行筑牢了根基。此刻&#xff0c;組件庫的建設之旅仍在繼續&#xff0c;我們將目光聚焦于另一個關鍵組件 —— 按鈕組件。按鈕作為用戶與界面…

鴻蒙OSS文件(視頻/圖片)壓縮上傳組件-能夠增刪改查

一、鴻蒙實現處理-壓縮上傳整體代碼處理邏輯 轉沙箱壓縮獲取憑證并上傳文件 文件準備&#xff08;拿到文件流&#xff09;獲取上傳憑證&#xff08;調接口1拿到file_name和upload_url&#xff09;執行文件上傳&#xff08;向階段2拿到的upload_url上傳文件&#xff09;更新列表…

河道流量監測,雷達流量計賦能水安全智慧守護

在蜿蜒的河道之上&#xff0c;水流的脈搏始終與人類文明的興衰緊密相連。從農田灌溉的水量調配到城市防洪的精準預警&#xff0c;從生態保護的水質溯源到水資源管理的決策&#xff0c;河道流量監測如同大地的 “血管檢測”&#xff0c;是守護水安全的第一道防線。傳統監測手段在…

CSS3 基礎(邊框效果)

一、邊框效果 屬性功能示例值說明border-radius創建圓角border-radius: 20px;設置元素的圓角半徑&#xff0c;支持像素&#xff08;px&#xff09;或百分比&#xff08;%&#xff09;。值為 50% 時可變為圓形。box-shadow添加陰影box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.5)…

零基礎小白如何上岸數模國獎

零基礎小白如何上岸數模國獎 我自己本人第一次參加數模國賽順利上岸國獎&#xff0c;當然那段經歷也是比較痛苦了&#xff0c;差不多也是從當年四月開始接觸數學建模&#xff0c;第一次參加媽媽杯成績并不理想&#xff0c;后面不斷參加數模比賽進行模擬&#xff0c;最后順利上岸…

SQL學習-常用函數

常見SQL函數使用 &#xff08;注意&#xff1a;不同的數據庫類型使用的語法不同&#xff09; 以下是MySQL和PostgreSQL在實現替換、抽取、拼接、分列四個常見字符串操作功能時的核心區別總結&#xff0c;按功能分類對比&#xff1a; 1. 替換&#xff08;Replace&#xff09; …

rt-linux下的cgroup cpu的死鎖bug

一、背景 rt-linux系統有其非常大的實時性的優勢&#xff0c;但是與之俱來的是該系統上有一些天然的缺陷。由于rt-linux系統允許進程在內核態執行的邏輯里&#xff0c;在持鎖期間&#xff0c;甚至持spinlock鎖期間&#xff0c;都能被其他進程搶占。這一特性能帶來實時性的好處…

java—12 kafka

目錄 一、消息隊列的優缺點 二、常用MQ 1. Kafka 2. RocketMQ 3. RabbitMQ 4. ActiveMQ 5. ZeroMQ 6. MQ選型對比 適用場景——從公司基礎建設力量角度出發 適用場景——從業務場景角度出發 四、基本概念和操作 1. kafka常用術語 2. kafka常用指令 3. 單播消息&a…

14【模塊學習】74HC595:使用學習

74HC595 1、74HC595簡介2、代碼演示2.1、驅動8位流水燈 3、74HC595級聯3.1、驅動16位流水燈3.2、驅動8位數碼管3.3、驅動8x8點陣屏幕3.4、8x8點陣屏幕滾動顯示 1、74HC595簡介 在51單片機中IO引腳資源十分的緊缺&#xff0c;所以常常需要使用75HC595芯片進行驅動那些需要占用多…

JAVA后端開發常用的LINUX命令總結

一、Linux常用命令大全&#xff08;2025年最新版&#xff09; 常用 Linux 命令 文件和目錄管理&#xff1a; cd&#xff1a;用于切換當前工作目錄&#xff0c;如cd /home/user。mkdir&#xff1a;創建新目錄&#xff0c;mkdir -p /home/user/mydir可遞歸創建多級目錄。pwd&am…

uniapp-商城-40-shop 購物車 選好了 進行訂單確認4 配送方式3 地址編輯

前面說了配送 和地址頁面 當地址頁面為空或需要添加地址時&#xff0c;需要添加地址。 我的地址頁面有個按鈕 就是添加地址 點擊 添加地址 按鈕 后&#xff0c;就會跳轉到地址添加的頁面 1、添加地址頁面 2、添加地址文件夾以及文件的創建 3、添加地址的代碼 <template…

現場問題排查-postgresql某表索引損壞導致指定數據無法更新影響卷宗材料上傳

問題現象 今天突然被拉進一個群&#xff0c;說某地區友商推送編目結果報錯&#xff0c;在我們自己的卷宗系統上傳材料也一直轉圈&#xff0c;也刪除不了案件卷宗&#xff0c;重置模板也沒用&#xff0c;只有個別案件有問題。雖然這事兒不屬于我負責&#xff0c;但還是抽時間給…

Redis01-基礎-入門

零、文章目錄 Redis01-基礎-入門 1、認識 NoSQL NoSQL 知識請參考&#xff1a;https://blog.csdn.net/liyou123456789/article/details/132612444 2、認識 Redis &#xff08;1&#xff09;簡介 Redis&#xff08;Remote Dictionary Server&#xff0c;遠程字典服務&…

【嘉立創EDA】如何在更新或轉換原理圖到PCB時,保留已有布局器件

文章路標?? :one: 文章解決問題:two: 主題內容:three: 參考方法be end..1?? 文章解決問題 操作環境:嘉立創EDA專業版 V2.2.37 本文使用嘉立創EDA,描述在更新或轉換原理圖到PCB時,保留已有布局器件的方法。本文將此過程記錄,以供有需要的讀者參考。 2?? 主題內容 …

03 APQC PROCESS CLASSIFICATION FRAMEWORK (PCF)

APQC流程分類框架&#xff08;APQC Process Classification Framework, PCF&#xff09;最初由美國生產力與質量中心&#xff08;American Productivity & Quality Center, APQC&#xff09;開發&#xff0c;旨在用于跨組織的流程性能基準比較。現在&#xff0c;它也常被用…

分析型數據庫入門指南:如何選擇適合你的實時分析工具?

一、什么是分析型數據庫&#xff1f;為什么需要它&#xff1f; 據Gartner最新報告顯示&#xff0c;超過75%的企業現已在關鍵業務部門部署了專門的分析型數據庫&#xff0c;這一比例還在持續增長。 隨著數據量呈指數級增長&#xff0c;傳統數據庫已無法滿足復雜分析場景的需求…

body Param Query 三個 不同的入參 分別是什么意思 在前端 要怎么傳 這三種不同的參數

在 NestJS 中&#xff0c;Body()、Param() 和 Query() 用于處理不同類型的請求參數。以下是它們的含義及前端傳遞方式&#xff1a; Body()&#xff1a;請求體參數 ? 含義&#xff1a;用于獲取請求體中的數據&#xff08;如 POST/PUT 請求中提交的 JSON、表單數據等&#xff09…

神經網絡(自己記錄)

一、神經網絡基礎 5分鐘-通俗易懂 - 神經網絡 反向傳播算法&#xff08;手算&#xff09;_嗶哩嗶哩_bilibili 二、GAT

Redis Slot 槽位分片具體案例

?鍵值槽位分配案例? 當執行 SET {kaigejava}k1 v1 時&#xff0c;Redis 會提取 {} 內的有效部分 kaigejava&#xff0c;通過 CRC16 算法計算哈希值&#xff0c;再對 16384 取余得到槽位。例如&#xff1a; 若計算結果為 1495&#xff0c;則該鍵會被分配到槽位 1495 對應的節…

【多模態模型】跨模態智能的核心技術與應用實踐

目錄 前言技術背景與價值當前技術痛點解決方案概述目標讀者說明 一、技術原理剖析核心概念圖解核心作用講解關鍵技術模塊說明技術選型對比 二、實戰演示環境配置要求核心代碼實現&#xff08;CLIP圖像-文本檢索&#xff09;運行結果驗證 三、性能對比測試方法論量化數據對比結果…