I have the following code, a very simple model User, and I am trying to update the password for an existing user; however, in BeforeSave, I could NOT get u *User data populated, so for the first time create, password is hashed, but when I update it, password become plain text. Any ideas what I do wrong here?
package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Username string `gorm:"type:varchar(40);unique" json:"username,omitempty"`
Password string `gorm:"size:255" json:"password,omitempty"`
NickName string `gorm:"type:varchar(32)" json:"nick_name,omitempty"`
}
func MakePassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
// BeforeSave : hook before a user is saved
func (u *User) BeforeSave(tx *gorm.DB) (err error) {
fmt.Println("================= user: ", u)
if u.Password != "" {
hash, err := MakePassword(u.Password)
if err != nil {
return nil
}
tx.Statement.SetColumn("password", hash)
}
return
}
func main() {
var connectionString = fmt.Sprintf(
"%s:%s@/%s?charset=utf8&parseTime=True&loc=Local",
"root", "password", "myproject",
)
db, _ := gorm.Open(mysql.Open(connectionString), &gorm.Config{})
db.AutoMigrate(&User{})
db.Save(&User{
Username: "username",
Password: "123",
})
// Up to this point, everything works, password is hashed.
// the following does not work as I expected
userMap := make(map[string]interface{})
userMap["id"] = 1
userMap["password"] = "new_password"
db.Model(&User{}).Where(&User{
Model: gorm.Model{ID: uint(userMap["id"].(int))},
}).Updates(userMap)
}