Rumah >pembangunan bahagian belakang >Golang >Golang GORM melaksanakan archived_at serupa dengan pemadaman lembut

Golang GORM melaksanakan archived_at serupa dengan pemadaman lembut

WBOY
WBOYke hadapan
2024-02-05 22:33:12457semak imbas

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

Kandungan soalan

Saya menggunakan GORM V1. Saya mempunyai keperluan, kami ingin menambah deleted_atarchived_at 列。实体可以存档和取消存档,默认情况下我们希望使用 archived_at seperti GORM untuk NULL untuk menanyakan rekod.

Idea semasa saya ialah menggunakan panggilan balik GORM untuk mendaftar panggilan balik

  1. Daftar panggil balik sebelum gorm:query panggil balik.
  2. Semak sama ada skema/model memerlukan medan arkib_di.
  3. Jika medan itu wujud, sila tambah syarat yang diperlukan.

Ini kedengaran hebat, tetapi bagaimana saya boleh menyalin yang setara dengan Unscoped() arkib dengan cekap.

  • Apakah cara idiomatik untuk mendapatkan rekod yang diarkibkan? Bagaimanakah cara saya menunjukkan sama ada lajur archived_at perlu ditambahkan pada panggilan balik yang diperlukan?
  • Saya juga menghadapi situasi di mana saya hanya mahu mendapatkan rekod yang diarkibkan (di mana archived_at BUKAN NULL).

EDIT - Kes penggunaan saya ialah menggunakan kedua-dua medan deleted_at dan deleted_atarchived_at, daripada menggunakan satu medan dan bukannya satu lagi. Saya mahu mengekalkan keupayaan untuk memadam lembut sambil menambah keupayaan untuk mengarkibkan entiti. Pengguna hanya boleh diarkibkan dan kemudian mungkin dipadamkan (dipadamkan lembut).


Jawapan Betul


Jemput maklum balas. Inilah yang saya fikirkan sekarang.

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;

Atas ialah kandungan terperinci Golang GORM melaksanakan archived_at serupa dengan pemadaman lembut. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam