Search code examples
gogo-gorm

Gorm BeforeCreate hook is not working to generate a UUID


I am trying to generate a UUID every time I create a company. I thought about doing it in the hook function, but it is not working. I tried to panic the program if it is executed, but the hook is not responding.

I followed the documentation on how I can implement the hook, but it does not work for me.

Hooks documentation: https://gorm.io/docs/hooks.html

import (
    "time"

    "github.com/jinzhu/gorm"
    uuid "github.com/satori/go.uuid"
)


type Base struct {
    ID        uuid.UUID  `gorm:"type:UUID;" json:"_id"`
    CreatedAt time.Time  `gorm:"type:Date;" json:"created_at"`
    UpdatedAt time.Time  `gorm:"type:Date;" json:"updated_at"`
    DeletedAt *time.Time `gorm:"type:Date;" json:"deleted_at"`
}

type CompanyModel struct {
    Base
    // Departments []DepartmentModel `gorm:"foreignKey:id" json:"departments"`
    Cvr         int               `gorm:"not null" json:"cvr"`
    Name        string            `gorm:"not null" json:"name"`
}

// BeforeCreate creates
func (u *Base) BeforeCreate(tx *gorm.DB) (err error) {
    u.ID = uuid.NewV4()
    panic(u.ID)
    return
}

// BeforeSave creates
func (u *Base) BeforeSave(tx *gorm.DB) (err error) {
    u.ID = uuid.NewV4()
    panic(u.ID)
    return
}

I am creating a company by the following

    tx := db.Session(&gorm.Session{SkipHooks: false}).Create(&models.CompanyModel{
        Cvr:  12333,
        Name: "test,
        // Departments: company.Departments,
    },
    )

The saved value when I execute is always:

[1.479ms] [rows:0] INSERT INTO "company_models" ("id","created_at","updated_at","deleted_at","cvr","name") VALUES ('00000000-0000-0000-0000-000000000000','2021-04-21 18:00:51.879','2021-04-21 18:00:51.879',NULL,12333,'test')

Solution

  • It looks like you are using gorm v1, and I think you need gorm v2. The import is "gorm.io/gorm".

    Minimum working example:

    package main
    
    import (
        "fmt"
        "gorm.io/driver/sqlite"
        "gorm.io/gorm"
    )
    
    type User struct {
        Id int
        Name string
    }
    
    func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
        u.Name = "Steve"
        return
    }
    
    func (u *User) BeforeSave(tx *gorm.DB) (err error) {
        u.Name = "Sally"
        return
    }
    
    func main() {
        db, err := gorm.Open(sqlite.Open("hooks.db"), &gorm.Config{})
        if err != nil {
            panic("failed to connect database")
        }
        db.AutoMigrate(&User{})
        user := User{
            Name: "Blake",
        }
        db.Create(&user)
        fmt.Println(user.Name)
        user.Name = "Tyler"
        db.Save(&user)
        fmt.Println(user.Name)
    }
    

    Prints:

    Steve
    Sally