最新公告
  • 欢迎您光临码农资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!加入我们
  • 有没有办法为结构内的每个结构执行 BeforeCreate 和 BeforeUpdate 挂钩?

    有没有办法为结构内的每个结构执行 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"`
    }
    
    想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
    本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
    如有侵权请发送邮件至1943759704@qq.com删除

    码农资源网 » 有没有办法为结构内的每个结构执行 BeforeCreate 和 BeforeUpdate 挂钩?
    • 7会员总数(位)
    • 25846资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 293稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情