2017-09-09 3 views
0

J'utilise gorm package comme ma bibliothèque de base de données dans golang. J'ai beaucoup de tables de base de données comme "Hôtes" ou "Commandes". Dans mon application CRUD, chaque contrôleur a la fonction setHost/setOrder ....Comment supprimer le code dupliqué dans Go avec Gorm

Je peux écrire cette fonction pour chaque contrôleur. Mais mieux serait d'avoir une seule fonction, où j'utiliserais d'abord param pour créer un objet avec la même classe que le paramètre, puis le passerais à gorm, qui le remplirait de données de la base de données, puis le retournerait. J'ai essayé d'utiliser réfléchir pour cela, mais j'ai échoué, parce que je ne le comprends probablement pas beaucoup.

Peut-être que je n'ai juste pas découvert de fonction dans la bibliothèque de gorm, ou je ne peux pas utiliser correctement le module de réflexion. Comment dois-je implémenter la fonction set. Est-il possible d'avoir cette implémentation, ou devrais-je plutôt répéter mon code?

type Host struct { 
    gorm.Model 
    name string 
} 

type Order struct { 
    gorm.Model 
    RoomSize int 
} 

func setOrder(c *gin.Context) (order models.Order) { 
    db := dbpkg.DBInstance(c) 
    id := new(ApplicationController).extractID(c) 

    db.First(&order, id) 

    if order.ID != id { 
    log.Panicf("No Object with the ID: %d", id) 
    } 
    return 
} 

func setHost(c *gin.Context) (host models.Host) { 
    db := dbpkg.DBInstance(c) 
    id := new(ApplicationController).extractID(c) 

    db.First(&host, id) 

    if host.ID != id { 
     log.Panicf("No Object with the ID: %d", id) 
    } 

    return host 
} 

func (ctrl ApplicationController) extractID(c *gin.Context) uint64 { 
    id, err := strconv.ParseUint(c.Params.ByName("id"), 10, 64) 
    if err != nil { 
     log.Panicf("ID: %s can not parse to an uint64", c.Params.ByName("id")) 
    } 
    return id 
} 

Répondre

0

Demandez à vos contrôleurs d'implémenter une interface qui a votre fonction extractID. Ensuite, implémentez cette extractID pour chacun de vos contrôleurs. Un peu comme cet exemple:

package main 

import "fmt" 

type IDInterface interface { 
    ExtractString() 
} 

type OrderController struct { 
    IDInterface 
    OrderData string 
} 

type HostController struct { 
    IDInterface 
    HostData string 
} 

func (c OrderController) ExtractString() { 
    fmt.Println("Data: " + c.OrderData) 
} 

func (c HostController) ExtractString() { 
    fmt.Println("Data: " + c.HostData) 
} 

func main() { 
    o := OrderController{OrderData: "I'm an order!"} 
    h := HostController{HostData: "I'm a host!"} 
    printData(o) 
    printData(h) 
} 

func printData(inter IDInterface) { 
    inter.ExtractString() 
} 

Remarque printData prend dans un IDInterface, mais main je ne fais que passer le contrôleur.