Maison >développement back-end >Golang >Existe-t-il un moyen de créer des hooks BeforeCreate et BeforeUpdate pour chaque structure au sein d'une structure ?

Existe-t-il un moyen de créer des hooks BeforeCreate et BeforeUpdate pour chaque structure au sein d'une structure ?

PHPz
PHPzavant
2024-02-05 21:48:08869parcourir

有没有办法为结构内的每个结构执行 BeforeCreate 和 BeforeUpdate 挂钩?

Contenu de la question

J'ai le code suivant :

type innerstructa struct {
 a string
}

type innerstructb struct {
 b string
}

func (a *a) beforecreate(scope *gorm.scope) error {
    return scope.setcolumn("a", uuid.new().string())
}

func (b *b) beforecreate(scope *gorm.scope) error {
    return scope.setcolumn("b", uuid.new().string())
}

type outerstruct struct {
    innerstructa
    innerstructb
    id      string `gorm:"type:varchar(40);not null"`
}

Quand je crée un enregistrement :

outerStructObject := OuterStruct{
        ID:          "sample_ID",
    }
err := db.Create(&outerStructObject).Error

Appelez uniquement l’un des hooks beforecreate(). Les autres beforecreate sont ignorés.

La version Gorm est Jinzhu/gorm v1.9.16

Existe-t-il un moyen d'appeler les deux hooks lors de l'appel de l'instruction create ?

Le hook beforecreate devrait être appelé pour deux structures internes - innerstructa et innerstructb.


Bonne réponse


Le commentaire de Peter est exact, je partagerai mes tests et commentaires ici mais en utilisant le référentiel officiel go -gorm/gorm et la dernière version v1.25.0 a des résultats très similaires et l'api quelques changements.

Lors de la création d'un registre externe, les objets internes peuvent être définis comme ceci :

func (o *outerstruct) beforecreate(tx *gorm.db) error {
    fmt.println("hook triggered: beforecreate for outerstruct")
    o.innerstructa.a = uuid.new().string()
    o.innerstructb.b = uuid.new().string()
    return nil
}

Pour déclencher des hooks d'objets internes, vous ne pouvez les créer que directement :

innera := innerstructa{
    a: "123",
}

errcreateinner := db.create(&innera).error

Voici un exemple isolé complet :

package main

import (
    "fmt"
    "log"

    "github.com/google/uuid"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

func main() {

    db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
    if err != nil {
        panic(err)
    }

    db.AutoMigrate(&InnerStructA{}, &InnerStructB{}, &OuterStruct{})

    outerStructObject := OuterStruct{
        ID: "sample_ID",
    }

    errCreate := db.Create(&outerStructObject).Error
    if err != nil {
        log.Fatal(errCreate)
    }

    var outer OuterStruct
    db.Last(&outer)
    fmt.Println("Last register: ", outer)

    // innerA := InnerStructA{
    //  A: "123",
    // }

    // errCreateInner := db.Create(&innerA).Error
    // if err != nil {
    //  log.Fatal(errCreateInner)
    // }
}

type InnerStructA struct {
    A string
}

type InnerStructB struct {
    B string
}

// This is not being called
func (a *InnerStructA) BeforeCreate(tx *gorm.DB) error {
    fmt.Println("Hook triggered: BeforeCreate for InnerStructA")
    // ...
    return nil
}

// This is not being called
func (b *InnerStructB) BeforeCreate(tx *gorm.DB) error {
    fmt.Println("Hook triggered: BeforeCreate for InnerStructB")
    // ...
    return nil
}

// This works!
func (o *OuterStruct) BeforeCreate(tx *gorm.DB) error {
    fmt.Println("Hook triggered: BeforeCreate for OuterStruct")
    o.InnerStructA.A = uuid.New().String()
    o.InnerStructB.B = uuid.New().String()
    return nil
}

type OuterStruct struct {
    InnerStructA
    InnerStructB
    ID string `gorm:"type:varchar(40);not null"`
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer