引言
我們不止一次在系列文章中講到模型的“軟刪除”功能,因為現實場景中為了保證資料可追溯,我們幾乎不會對資料庫進行物理刪除。刪除資料有可能會造成資料一致性的破壞,進而導致業務邏輯無法跑通。所以,軟刪除的概念,極為重要。
本文我們仍然不厭其煩地講解軟刪除的功能。
物理刪除
其實就是真實地把資料從資料庫條目清除,laravel模型提供了開箱即用的方法。比如下面這樣使用:
$event = Event::find(12);
$event->delete();
首先使用primary key查詢出需要的條目,返回一個Event物件例項,然後呼叫 delete 方法進行刪除。真實的SQL如下:
DELETE FROM events WHERE id = 12;
laravel提供了許多語法糖,上面使用 find 和 delete 兩個步驟,可以縮減為一個方法 destroy,用法如下:
Event::destroy(12);
這樣一行就搞定了。
軟刪除
在許多情況下,你不會真正想要從資料庫中刪除記錄,而是用一種不再在應用程式中顯示它們的方式對其進行註釋。這就是所謂的軟刪除。
Laravel本身支援軟刪除,只需要進行少量的配置更改,以確保在執行delete或destroy時,模型的記錄不會被實際刪除。作為一個例子,我們修改Event模型以支援軟刪除。
首先建立一個新的遷移,將名為deleted_at的列新增到events表中:
php artisan make:migration add_soft_delete_to_events --table=events
執行成功,輸出內容如下:
Created Migration: 2020_10_08_184402_add_soft_delete_to_events
接著在生成的遷移檔案內實現遷移使用的 up 方法:
public function up()
{
Schema::table('events', function(Blueprint $table)
{
$table->softDeletes();
});
}
還有用於遷移回滾的 down 方法:
public function down()
{
Schema::table('events', function(Blueprint $table)
{
$table->dropColumn('deleted_at');
});
}
修改完畢,在命令列執行遷移指令:
php artisan migrate
執行成功輸出內容:
Migrating: 2020_10_08_184402_add_soft_delete_to_events
Migrated: 2020_10_08_184402_add_soft_delete_to_events
模型SoftDelete
有了資料庫表的支援,我們才能在模型內使用軟刪除的功能。
其實原理很簡單,就是為模型追加一個全域性作用域,為每個查詢子句追加上如下篩選條件:
WHERE deleted_at IS NULL
laravel已經為我們寫好這部分邏輯了,在模型內引入如下trait:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
在類內引入trait,並手動指定修改器,也就是說deleted_at欄位,我們使用 Carbon 進行例項化操作。
class Event extends Model {
use SoftDeletes;
protected $dates = ['created_at','deleted_at','started_at','updated_at'];
}
儲存這些更改之後,下次刪除與此模型關聯的記錄時,deleted_at列將被設定為當前時間。任何設定deleted_at為日期時間值的記錄,都不會包含在任何查詢結果中,因此看起來已經被刪除了。
這樣操作非常有用,因為誤刪除的資料,隨時可以通過設定 deleted_at = null 而恢復到正常的業務流程中,比如刪除的使用者,刪除的訂單,等等其他資源。
如果你在程式碼內要堅持查詢全量資料,也包含軟刪除了的資料,那麼程式碼這樣寫:
$events = Event::withTrashed()->get();
寫在最後
本文我們有重溫了laravel的模型軟刪除功能,通過建立遷移檔案,修改資料庫表,追加軟刪除欄位。並在模型內引入 SoftDelete 程式碼片段引入軟刪除的程式功能。
Happy coding :-)
我是@程式設計師小助手,專注程式設計知識,圈子動態的IT領域原創作者
本作品採用《CC 協議》,轉載必須註明作者和本文連結