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

Create Update Delete

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