Home >Backend Development >Golang >Golang GORM implements archived_at similar to soft deletion
I am using GORM V1. I have a requirement where we want to add a archived_at
column similar to GORM deleted_at
. Entities can be archived and unarchived, and by default we want to query records with archived_at
being NULL.
My current idea is to use GORM callbacks to register callbacks
This sounds great, but how do I efficiently copy the equivalent of the archive's Unscoped() .
archived_at
column should be added to the necessary callback? archived_at
IS NOT NULL). Edit - My use case is to use both the deleted_at
and archived_at
fields, rather than using one field instead of the other. I want to keep the ability to soft delete while adding the ability to archive entities. The user may simply be archived and then possibly deleted (soft deleted).
Invite feedback. This is what I'm thinking of right now.
Callback.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)) } } }
scope.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;
The above is the detailed content of Golang GORM implements archived_at similar to soft deletion. For more information, please follow other related articles on the PHP Chinese website!