I'm developping an API with lots of models using go-gorm. So far for the "GetAll" function, i've been using the following (simplified) :
func GetAllUsers(w,r){
//... get params and do some check
pages := []*models.User{} //<-main problem I have to give the full type
models.GetDB().Model(&models.User{}).Offset(offset).Limit(pagesize).Find(&pages)
//do the http response(w,pages)
}
But I'd like to avoid copying/pasting the function to just modify the type (here models.User) to get all models from db.
I did try different approach using reflect or interface but none seems to work like :
func GenericGetAll(w http.ResponseWriter, r *http.Request, data interface{}) {
dtype := reflect.TypeOf(data)
pages := reflect.New(reflect.SliceOf(dtype)).Elem().Interface()
log.Printf("%+v", pages)
//reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(data)), 0, 20)
//new([]gorm.Model)
GetDB().LogMode(true).Model(data).Offset(offset).Limit(pagesize).Find(&pages)
utils.Respond(w, pages)
}
So I could use this directly in my handlers :
GenericGetAll(w,r,&models.User{}) for user
GenericGetAll(w,r,&models.Product{}) for Product
GenericGetAll(w,r,&models.Company{}) for Company
This would be cleaner than copying/pasting the other function just to modify the type ...
But using those different approach give problems :
- []*interface{}, I lose the table name and get a sql error because tablename '' doesn't exist
- new([]gorm.Model) it lose my tablename and use gorm.model default tablename :/
- reflect.New(reflect.SliceOf(dtype)).Elem().Interface() and I get an error : unsupported destination, should be slice or struct evenif it did create the slice :/ the log.printf() give an empty array []
How should I use reflect to get a slice from the type in argument of the function ?
Is this only doable with Golang ? I know that polymorphism doesn't exist in golang but ... this is a required features or is there something magic I don't know about golang ? ^^.
Thanks