#Using Generics on GORM

7 messages · Page 1 of 1 (latest)

dusky dove
#

Hi guys. I'm having an issue using an interface to insert data using GORM:

func MyFunc (...){
    ...
    entity, errEntity := repositories.Create(&tenant)
    ...
}

func Create(entity interface{}) (interface{}, error) {    
    db, errDb := helpers.DbInit()
    if errDb != nil {
        return nil, db.Error
    }

    h := helpers.NewDbConnection(db)
    result := h.DB.Create(&entity)
    if result.Error != nil {
        return nil, result.Error
    }

    return entity, nil
}

Error:

INSERT INTO "tenant" ("cognito_sub","email","name","parent_id","tenant_type","is_active","created_by","created_at","updated_by","updated_at") VALUES  RETURNING "id"

{"message":"Error executing database operation","details":"unsupported data"}

looks like values are missing on the SQL statement. The way I found to make it work is to pass the type, like this:

func MyFunc (...){
    ...
    entity, errEntity := repositories.Create[models.Tenant](&tenant)
    ...
}

func Create[T any](entity interface{}) (interface{}, error) {    
    var returnEntity T
    if entity, ok := requestedEntity.(T); ok {
        returnEntity = entity
    }

    db, errDb := helpers.DbInit()
    if errDb != nil {
        return nil, db.Error
    }

    h := helpers.NewDbConnection(db)
    result := h.DB.Create(&returnEntity)
    if result.Error != nil {
        return nil, result.Error
    }

    return returnEntity, nil
}

I was wondering if I could solve it without having to pass the type

dusky dove
#

Thoughts on this one?

warped quail
#

func Create[T any](entity T) (T, error) or something like that might work

dusky dove
#

yeah, that works. Thanks @warped quail

#

Now I'm wondering If there is any way to create an interface and use a function as a parameter, like this (i know is not possible to have generics on an interface, but there is another way to implement something like that?):

type GenericRepository interface{
    Create[T any](entity T) (T, error)
}

func (db *gorm.DB) Create[T any](entity T) (T, error) {
    conn, errConn := helpers.GetDBConnection()
    if errConn != nil {
        return entity, errConn
    }

    result := conn.DB.Create(&entity)
    if result.Error != nil {
        return entity, result.Error
    }

    return entity, nil
}
warped quail
#

The [T any] would have to be attached to the interface, not the method, if it is going to work at all (but not sure it would)

dusky dove
#

But there is an undefined T error on the Create method