How to Update Multiple Attribute With Struct

Viewed 4556

I was trying to make a function that can update user by given parameter.

My Method:

func UpdateMultiple(db *gorm.DB, user *User, id uint32) error {
    usr := User{}

    err := db.Debug().Model(User{}).Where("id = ?", id).Updates(map[string]interface{}{"email": user.Email, "is_active": false}).Take(&usr).Error
    if err != nil {
        return err
    }
    return nil
}

And Using like this:

Updater := &User{
    Email:    holder.Email,
    IsActive: false,
}
err = UpdateMultiple(s.DB, Updater, id)

It is working fine for now.But If want to update another field i have to change my UpdateMultiple() method. Is there any other way i can update without changing method but only changing given parameters value?

2 Answers

You can pass your User model to the Updates function, it will update all struct fields with non blank value (which means that all fields should be pointers, in order to make the best use of this feature). The code would look like this:

func UpdateMultiple(db *gorm.DB, user *User, id uint32) error {
     return db.Debug().
          Model(User{}).
          Where("id = ?", id).
          Updates(user).Error

}

See some examples from the official documentation:

// Update multiple attributes with `struct`, will only update those changed & non blank fields
db.Model(&user).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;

// WARNING when update with struct, GORM will only update those fields that with non blank value
// For below Update, nothing will be updated as "", 0, false are blank values of their types
db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})

Since you need dynamic field update, fetch user first by id

user := &User{}
db.First(&user, id)

Update the field you want to update

user.Email = "a@a.com"
user.IsActive = false

And update the user info

db.Save(&user)

Or

Create map[string]interface{} and add which field you want to update.

mp := make(map[string]interface{})
mp["email"] = holder.Email
mp["is_active"] =  false

And update the user

db.Model(User{}).Where("id = ?", id).Updates(mp)
Related