OOro

Soft Delete 软删除扩展

使用官方 softdelete 扩展把软删除字段从核心模型中拆出来,并复用 Oro 的查询、删除、恢复能力。

extensions/softdelete 提供约定软删除字段和字段定义方法。软删除能力仍然走 Oro 的模型查询链路:普通查询自动隐藏已删除数据,OnlyDeleted 查询已删除数据,WithDeleted 取消默认过滤。

import "github.com/duxweb/oro/extensions/softdelete"

安装

软删除扩展没有运行时配置,注册后用于表达项目依赖关系:

db, err := oro.Open(oro.Config{
    Connections: map[string]oro.ConnectionConfig{
        "default": {Driver: sqlite.Open("app.db")},
    },
    Extensions: []oro.Extension{
        softdelete.Extension(),
    },
})

模型字段

推荐直接嵌入 softdelete.SoftDeleteFields

type Product struct {
    oro.Model
    softdelete.SoftDeleteFields

    Code string
}

func (Product) Define(s *oro.SchemaBuilder) {
    s.Table("products")
    s.Field("Code").String().Unique()
}

嵌入字段会自动定义约定列 DeletedAt -> deleted_at,类型是 oro.Null[time.Time]

删除与恢复

_, err := db.Use[Product]().Where("ID", id).Delete(ctx)

模型包含软删除字段时,Delete 会更新 deleted_at,不会物理删除。

product, err := db.Use[Product]().OnlyDeleted().Where("ID", id).First(ctx)
_, err = db.Use[Product]().WithDeleted().Where("ID", id).Restore(ctx)

Restore 会把软删除字段恢复为 NULL

作用范围

默认过滤(deleted_at IS NULL)现在覆盖所有解析到已注册软删除模型的读取路径,不再只作用于 Use[T]() 模型查询:

  • 通过 .With(...) 预加载的关联会排除已软删除的关联数据。旧版本会把它们一并返回,现已修复。
  • 底层 db.Table("...") 读取映射到已注册软删除模型的表时,也会排除已软删除的数据。

模型查询和关联查询仍然保留豁免入口:WithDeleted() 返回包含已删除的数据,OnlyDeleted() 只返回已删除的数据。需要完全不过滤的原生读取时,db.Raw(...) 不会被加上软删除过滤,请按需自行编写条件。

物理删除

需要真正删除记录时使用 ForceDelete

_, err := db.Use[Product]().Where("ID", id).ForceDelete(ctx)

自定义字段

如果不使用约定字段,可以直接用核心字段构建器标记软删除列:

type Product struct {
    oro.Model
    RemovedAt oro.Null[time.Time]
}

func (Product) Define(s *oro.SchemaBuilder) {
    s.Table("products")
    s.Field("RemovedAt").Column("removed_at").Timestamp().SoftDelete()
}
编辑此页