Heim >Backend-Entwicklung >Golang >Golang GORM implementiert archived_at ähnlich wie Soft Deletion

Golang GORM implementiert archived_at ähnlich wie Soft Deletion

WBOY
WBOYnach vorne
2024-02-05 22:33:12458Durchsuche

Golang GORM 实现类似于软删除的archived_at

Frageninhalt

Ich verwende GORM V1. Ich habe eine Anforderung: Wir möchten ein GORM-ähnliches deleted_atarchived_at 列。实体可以存档和取消存档,默认情况下我们希望使用 archived_at für NULL hinzufügen, um Datensätze abzufragen.

Meine aktuelle Idee ist, GORM-Rückrufe zu verwenden, um Rückrufe zu registrieren

  1. Rückruf vor gorm:query-Rückruf registrieren.
  2. Überprüfen Sie, ob das Schema/Modell das Feld archived_at erfordert.
  3. Wenn das Feld vorhanden ist, fügen Sie bitte die erforderlichen Bedingungen hinzu.

Das klingt großartig, aber wie kopiere ich effizient das Äquivalent von Unscoped() des Archivs?

  • Was ist der idiomatische Weg, um archivierte Aufzeichnungen zu erhalten? Wie gebe ich an, ob dem erforderlichen Rückruf eine archived_at-Spalte hinzugefügt werden soll?
  • Ich stoße auch auf eine Situation, in der ich nur archivierte Datensätze erhalten möchte (wobei archived_at NICHT NULL IST).

BEARBEITEN – Mein Anwendungsfall besteht darin, sowohl die Felder deleted_at als auch deleted_atarchived_at zu verwenden, anstatt ein Feld anstelle des anderen zu verwenden. Ich möchte die Möglichkeit zum vorläufigen Löschen beibehalten und gleichzeitig die Möglichkeit zum Archivieren von Entitäten hinzufügen. Der Benutzer kann einfach archiviert und dann möglicherweise gelöscht werden (vorläufig gelöscht).


Richtige Antwort


Feedback einladen. Daran denke ich gerade.

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;

Das obige ist der detaillierte Inhalt vonGolang GORM implementiert archived_at ähnlich wie Soft Deletion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen