首页  >  文章  >  后端开发  >  有没有办法为结构内的每个结构执行 BeforeCreate 和 BeforeUpdate 挂钩?

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

PHPz
PHPz转载
2024-02-05 21:48:08859浏览

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

问题内容

我有以下代码:

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"`
}

当我创建记录时:

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

仅调用 beforecreate() 挂钩之一。其他 beforecreate 被跳过。

gorm版本为jinzhu/gorm v1.9.16

有没有一种方法可以在调用 create 语句时调用两个钩子?

预计为两个内部结构调用 beforecreate 挂钩 - innerstructa 和 innerstructb。


正确答案


peter 的评论是准确的,我将在这里分享我的测试和评论,但使用官方存储库 go -gorm/gorm 和最新版本 v1.25.0 具有非常相似的结果和 api 中的一些更改。

创建外部注册表时,内部对象可以这样设置:

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
}

要触发内部对象钩子,只能通过直接创建它们:

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

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

这是一个完整的孤立示例:

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"`
}

以上是有没有办法为结构内的每个结构执行 BeforeCreate 和 BeforeUpdate 挂钩?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除