goinheritancego-gormcode-reuse

Gorm: Is it possible to define shared methods for common db operations (e.g get by id)?


Using go and gorm in a project.

I have created a dao level to wrap the database operations, each table has its own dao type.


Current code


What I want to achieve

Wondering is it possible to write a BaseDao in go, with a single Get() method, so that I don't have to write this code 2 times.

This is very easy in Java, but since go is very different, and don't support real inheritance (I guess), not sure is this possible.


What I have tried


Questions


Solution

  • If you're trying to completely bypass writing a Get() method for each DAO, your only solution is to return an interface{} from this method. However this approach creates two problems :

    The solution I think the best, is to share most of the code by using structure embedding, and write lightweight wrappers for each DAO to convert the unsafe interface{} into a type-safe value.

    Example

    First create your base DAO with a generic Get() method. There is no type generics in Go, so you should return an interface{} here.

    type BaseDAO struct {}
    
    func (*BaseDAO) Get(id uint64) (interface{}, error) {}
    

    Then, for each type of data, create a specific DAO implementation, embedding BaseDAO :

    type FooModel = string
    
    type FooDAO struct {
        // Embbeding BaseDAO by not specifying a name on this field
        // BaseDAO methods can be called from FooDAO instances
        BaseDAO
    }
    
    func (foo *FooDAO) Get(id uint64) (FooModel, error) {
        // Call the shared Get() method from BaseDAO.
        // You can see this just like a `super.Get()` call in Java.
        result, _ := foo.BaseDAO.Get(id)
        return result.(FooModel), nil
    }