20 個 Laravel Eloquent 必備的實用技巧

20 個 Laravel Eloquent 必備的實用技巧

Eloquent ORM 看似簡單,但在底層卻隱藏著許多不為人知的技巧和功能。這篇文章將帶你了解一些實用的小竅門。

1. 增加與減少字段值

代替傳統方式:

$article = Article::find($article_id); $article->read_count++; $article->save();

可以使用更簡潔的方法:

$article = Article::find($article_id); $article->increment('read_count');

更多用法示例:

Article::find($article_id)->increment('read_count'); Article::find($article_id)->increment('read_count', 10); // 增加10 Product::find($produce_id)->decrement('stock'); // 減少1

2. X 方法失敗后執行 Y 方法

Eloquent 提供了一些便捷方法來簡化操作流程。

實例 1:findOrFail()

代替:

$user = User::find($id); if (!$user) {     abort(404); }

直接寫為:

$user = User::findOrFail($id);

實例 2:firstOrCreate()

代替:

$user = User::where('email', $email)->first(); if (!$user) {     User::create([         'email' => $email     ]); }

可以寫成:

$user = User::firstOrCreate(['email' => $email]);

3. 模型中的 boot() 方法

在模型中使用 boot() 可以修改默認行為,例如監聽事件

class User extends Model {     public static function boot()     {         parent::boot();         static::updating(function ($model) {             // 可以在這里記錄日志或修改字段值         });     } }

創建時自動設置 UUID 示例:

public static function boot() {     parent::boot();     self::creating(function ($model) {         $model->uuid = (string)Uuid::generate();     }); }

4. 帶條件和排序的關聯關系

普通關聯定義:

public function users() {     return $this->hasMany('AppUser'); }

也可以添加查詢條件和排序:

public function approvedUsers() {     return $this->hasMany('AppUser')->where('approved', 1)->orderBy('email'); }

5. 模型常用屬性配置

常見模型屬性設置如下:

class User extends Model {     protected $table = 'users';     protected $fillable = ['email', 'password'];     protected $dates = ['created_at', 'deleted_at'];     protected $appends = ['field1', 'field2']; }

其他可配置項包括:

protected $primaryKey = 'uuid'; // 自定義主鍵 public $incrementing = false; // 關閉自增 protected $perPage = 25; // 分頁數量 const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; // 自定義時間戳字段 public $timestamps = false; // 關閉時間戳

6. 根據多個 ID 查詢數據

find() 不僅支持單個 ID 查詢,還支持數組傳參:

$users = User::find([1, 2, 3]);

7. WhereX 魔術方法

可以將以下代碼:

$users = User::where('approved', 1)->get();

改寫為:

$users = User::whereApproved(1)->get();

也支持時間相關查詢:

User::wheredate('created_at', date('Y-m-d')); User::whereDay('created_at', date('d')); User::whereMonth('created_at', date('m')); User::whereYear('created_at', date('Y'));

8. 使用關聯進行排序

假設我們想根據主題最新帖子進行排序:

定義關聯:

public function latestPost() {     return $this->hasOne(AppPost::class)->latest(); }

控制器中使用:

$users = Topic::with('latestPost')->get()->sortByDesc('latestPost.created_at');

9. 使用 when() 替代 if-else

替代傳統的 if-else 寫法:

if (request('filter_by') == 'likes') {     $query->where('likes', '>', request('likes_amount', 0)); } if (request('filter_by') == 'date') {     $query->orderBy('created_at', request('ordering_rule', 'desc')); }

使用 when() 更優雅:

$query = Author::query(); $query->when(request('filter_by') == 'likes', function ($q) {     return $q->where('likes', '>', request('likes_amount', 0)); }); $query->when(request('filter_by') == 'date', function ($q) {     return $q->orderBy('created_at', request('ordering_rule', 'desc')); });

10. 默認模型返回

避免訪問不存在的關系對象導致錯誤:

原寫法可能報錯:

{{ $post->author->name }}

優化為返回默認模型:

public function author() {     return $this->belongsTo('AppAuthor')->withDefault(); }

還可以指定默認值:

public function author() {     return $this->belongsTo('AppAuthor')->withDefault([         'name' => 'Guest Author'     ]); }

11. 使用訪問器進行排序

當使用訪問器排序時,不能直接使用 orderBy():

$clients = Client::orderBy('full_name')->get(); // 無效

應改為:

$clients = Client::get()->sortBy('full_name'); // 有效

注意使用的是 sortBy() 而不是 orderBy()。


12. 全局作用域默認排序

在 boot() 中設置全局作用域實現默認排序:

protected static function boot() {     parent::boot(); <pre class="brush:php;toolbar:false">static::addGlobalScope('order', function (Builder $builder) {     $builder->orderBy('name', 'asc'); });

}


13. 原生 sql 查詢方法

Eloquent 支持嵌入原生 SQL 查詢:

// whereRaw $orders = DB::table('orders') ->whereRaw('price > IF(state = "TX", ?, 100)', [200]) ->get();</p><p>// havingRaw Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();</p><p>// orderByRaw User::where('created_at', '>', '2016-01-01') ->orderByRaw('(updated_at - created_at) desc') ->get();

14. 復制模型記錄

使用 replicate() 快速復制數據:

$task = Tasks::find(1); $newTask = $task->replicate(); $newTask->save();

15. chunk() 分塊處理大數據

代替一次性加載全部數據:

$users = User::all(); foreach ($users as $user) { // ... }

使用 chunk() 分批處理:

User::chunk(100, function ($users) { foreach ($users as $user) { // ... } });

16. 創建模型時生成配套文件

Artisan 命令:

php artisan make:model Company -mcr

參數說明:

  • -m 生成遷移文件
  • -c 生成控制器
  • -r 生成資源控制器

17. save() 時控制 updated_at

可以通過參數阻止自動更新時間戳:

$product = Product::find($id); $product->updated_at = '2019-01-01 10:00:00'; $product->save(['timestamps' => false]);

18. update() 返回受影響行數

update() 方法會返回數據庫中受影響的行數:

$result = $products->whereNull('category_id')->update(['category_id' => 2]);

此時 $result 就是被更新的數據條數。


19. 混合 and/or 的查詢

SQL 查詢:

WHERE (gender = 'Male' AND age >= 18) OR (gender = 'Female' AND age >= 65)

對應 Eloquent 寫法:

 $q->where(function ($query) { $query->where('gender', 'Male')->where('age', '>=', 18); })->orWhere(function ($query) { $query->where('gender', '

? 版權聲明
THE END
喜歡就支持一下吧
點贊6 分享