Your Question
Hello, I want to make a wrapper function for gorm Save/Create/Delete that uses an empty interface. However, if we pass a struct object address to an empty interface argument, and then get this value via reflect library and then passing an address I get an error (I listed up the errors below). When I passed the actual object without an address, it was successful. Or, when I cast the value obviously, it was also successful even if I pass struct address. As much as possible, I don't want to type casting because I want to use this wrapper for many struct objects. Is there any solution? Thank you very much for your help in advance.
type User struct {
ID string
Name string
}
func main() {
// ---- be skipped to write down get gorm instance
tx := initDB() // dummy
tx.Begin()
user := User{ID: "id1", Name: "user1"}
upsert(tx, &user)
tx.Commit()
// .......
}
func upsert(tx *gorm.DB, value interface{}) error {
rValue := reflect.ValueOf(value)
actualValue := rValue.Interface()
// dummy code. we execute one of them
ref := tx.Save(actualValue) // works
ref := tx.Save(&actualValue) // infinite loop is in this line https://github.com/go-gorm/gorm/blob/5e599a07ec6aacd85b7806805908c4a78fa0e5ce/callbacks.go#L119
ref := tx.Create(actualValue) // works
ref := tx.Create(&actualValue) // happening an error of "unsupported data" is in this line https://github.com/go-gorm/gorm/blob/5e599a07ec6aacd85b7806805908c4a78fa0e5ce/callbacks/create.go#L344
castActualValue := actualValue.(*User)
ref := tx.Save(&castActualValue) // works
ref := tx.Create(&castActualValue) // works
value = &actualValue
return ref.Error
}
The document you expected this should be explained
Expected answer
the way how to avoid an error when passing the target gorm DB model struct address to an empty interface argument in gorm caller function, and then getting actual value via reflect library and then passing an address to Create/Save function