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

2024年 2月 5日 59.8k 0

有没有办法为结构内的每个结构执行 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 挂钩?的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论