Search code examples
gogo-gorm

How to use setter for field in Golang


I'm using Gorm to define my models and connect to the database. I have a user type like this

type User struct {
    gorm.Model
    Email    string `gorm:"unique"`
    Password string
    Language *string
}

Is there a way to use a setter for my fields? What I want to achieve is to hash the password before saving it to the database (I already have the function to do that) and prevent a password from being set like this

user.Password = "non hashed"

Edit based on @JonathanHall comment:

I figured out how to create a setter, but I'm not sure if I'm using the correct hook. Is BeforeCreate the right one or is better BeforeSave? If a users update their password (from an interface) does the setter still work?

func (u *User) BeforeCreate(tx *gorm.DB) error {
    password, err := utils.HashPassword(u.Password)

    if err != nil {
        return err
    }

    u.Password = password
    return nil

}


Solution

  • You can create a custom type and implement these two function for it so in case of reading value by sql library Value() method and in case of scanning a value from query to your field Scan() method is going to be called.

    Scan(value any) error
    Value() (driver.Value, error)
    

    for example:

    type CustomPasswordField string
    
    func (c *CustomPasswordField) Scan(value any) error {
        // Do your scan
        return nil
    }
    
    func (c *CustomPasswordField) Value() (driver.Value, error) {
        // return the value that you like to store in db
        // for example the hash of the password
        return "", nil
    }