最新公告
  • 欢迎您光临码农资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!加入我们
  • Golang GORM 实现类似于软删除的archived_at

    golang gorm 实现类似于软删除的archived_at

    问题内容

    我正在使用 GORM V1。我有一个要求,我们想要添加一个类似于 GORM deleted_atarchived_at 列。实体可以存档和取消存档,默认情况下我们希望使用 archived_at 为 NULL 来查询记录。

    我目前的想法是利用 GORM 回调来注册回调

    1. 在 gorm:query 回调之前注册回调。
    2. 检查架构/模型是否需要 archived_at 字段。
    3. 如果确实有该字段,请添加必要条件。

    这听起来不错,但我如何有效地复制相当于存档的 Unscoped() 。

    • 获取存档记录的惯用方法是什么?如何指示 archived_at 列是否应添加到必要的回调中?
    • 我还会遇到这样的情况:我只想获取存档记录(其中 archived_at IS NOT NULL)。

    编辑 – 我的用例是同时使用 deleted_atarchived_at 字段,而不是使用一个字段代替另一个字段。我想保留软删除的能力,同时添加归档实体的能力。用户可能只是被存档,然后可能被删除(软删除)。

    正确答案

    邀请反馈。这是我目前想到的。

    回调.go

    package db
    
    import (
        "fmt"
        "reflect"
    
        "gorm.io/gorm"
    )
    
    const (
        gormsettingkeyunscopearchive = "unscope_archive"
        structfieldnamearchivedat    = "archivedat"
    )
    
    // archivedquerycallback - conditionally adds "where archived_at is null" if the model being queried has the following
    // 1. struct field represented by structfieldnamearchivedat
    // 2. gorm instance setting gormsettingkeyunscopearchive, see unscopearchive
    func archivedquerycallback(db *gorm.db) {
        // check if model is a pointer and has an indirect struct type
        if db.statement.model != nil &&
            reflect.typeof(db.statement.model).kind() == reflect.ptr &&
            reflect.indirect(reflect.valueof(db.statement.model)).kind() == reflect.struct {
            stmt := &gorm.statement{db: db}
            parseerr := stmt.parse(db.statement.model)
            if parseerr != nil {
                panic(parseerr)
            }
    
            if _, archivedatexists := stmt.schema.fieldsbyname[structfieldnamearchivedat]; archivedatexists {
                v, ok := db.instanceget(gormsettingkeyunscopearchive)
                if ok {
                    if v == true {
                        return
                    }
                }
    
                db.where(fmt.sprintf("%s is null", stmt.schema.fieldsbyname[structfieldnamearchivedat].dbname))
            }
        }
    }
    

    范围.go

    // unscopearchive - sets a true value for the key gormsettingkeyunscopearchive
    func unscopearchive(db *gorm.db) *gorm.db {
        db = db.instanceset(gormsettingkeyunscopearchive, true)
    
        return db
    }
    
    

    main.go

       type User {
           ID           string         `gorm:"primary_key" json:"id" valid:"uuidv4, optional"`
        CreatedAt    time.Time      `valid:"-" json:"created_at"`
        UpdatedAt    time.Time      `valid:"-" json:"-"`
        DeletedAt    gorm.DeletedAt `sql:"index" valid:"-" json:"-"`
        ArchivedAt   time.Time
       }
    
       var user []User
       ctx := context.Background()
       dbClient := InitializeGORM() //helper 
       _ := dbClient.WithContext(ctx).Find(&user).Error // SELECT * FROM users WHERE deleted_at IS NULL AND archived_at IS NULL;
    
       _ := dbClient.WithContext(ctx).Scopes(UnscopeArchive).Find(&user).Error // SELECT * FROM users WHERE deleted_at IS NULL;
    
    想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
    本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
    如有侵权请发送邮件至1943759704@qq.com删除

    码农资源网 » Golang GORM 实现类似于软删除的archived_at
    • 7会员总数(位)
    • 25846资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 293稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情