如果你是透過 Eloquent 操作資料庫 CRUD,當你對資料做增刪時會自動觸發相關的 Event Hook,例如 Insert 前觸發 creating Hook、Insert 後會觸發 created Hook。想知道總共有哪些 Hook 可以看官網

關聯刪除

Event Hook 最常被用到的地方是 Relation data delete/update Cascade,也就是假如一個使用者被刪除,他過去的文章也要一併被刪除 — 我們稱做「關聯刪除」。Laravel 預設不會幫我們做關聯刪除,這種時候就很適合在 deleting Hook 裡註冊一個 Article delete event。(見下方範例)

// in App\\Models\\User.php

class User
{
	// ...

	/**
		* 先建立 User 跟 Article 之間的關聯
    */
	public function articles()
	{
		return $this->hasMany(Article::class);
	}

	public static function boot()
	{
		parent::boot();

		/**
      * 針對 deleting event hook 註冊關聯刪除
      */
		static::deleting(function (User $user) {
			$user->articles->each(function ($article) {
				$article->delete();
			});
		});
	}
}

關聯更新

除了關聯資料刪除,也可以做關聯更新,也就是 Hook 裡撰寫一般的 Eloquent 操作。例如你有一個表格 factory_counts ,用以紀錄工廠底下所有倉庫的貨存量,如果有一個倉庫被刪除,貨存量就要減去該倉庫的擁有數。

// in App\\Models\\Storehouse.php

/* 倉庫 */
class Storehouse
{
	/* 倉庫所存的商品 */
	public function Goods()
	{
		return $this->hasMany(Goods::class);
	}

	/* 當倉庫被刪除時減去貨存量 */
	public static function boot()
	{
		static::deleting(function (Storehouse $store) {
			$goodsNum = $store->goods()->count();

			Factory::where('id', $store->factory_id)->decrement('counts', $goodsNum);
		});
	}
}

常見問題

明明做了刪除的動作,卻沒有觸發 deleting Event!

問題描述:我執行了 User 的刪除,但卻沒有觸發 User 的 deleting Hook。

這是一個非常常見的問題。

通常發生原因為:你實際只是操作了 SQL Query,並沒有真的透過 Eloquent 獲取 instance,對它進行操作,所以 Hook 沒有觸發。

例如你刪除的指令通常都這樣寫:

Factory::where('id', $id)->delete();

這行動作只是執行了 SQL Query,並沒有真的獲取一個 Query Result Collection/Object。只有對一個實際 Query 出的 instance 進行操作才會觸發 Hook。