Как удалить повторяющийся код в Go с Gorm

Я использую пакет gorm в качестве библиотеки базы данных в golang. У меня есть много таблиц базы данных, таких как «Хосты» или «Заказы». В моем приложении CRUD каждый контроллер имеет функцию setHost / setOrder ....

Я могу написать эту заданную функцию для каждого контроллера. Но лучшим способом было бы иметь только одну функцию, где я бы использовал первый параметр для создания объекта с тем же классом, что и параметр, а затем передал бы его в gorm, который заполнит его данными из базы данных, а затем вернет его. Я пытался использовать для этого рефлексию, но у меня ничего не вышло, потому что я, наверное, не очень разбираюсь в этом.

Возможно, я просто не обнаружил какую-то функцию в библиотеке gorm, или я не могу правильно использовать пакет отражения. Как мне реализовать заданную функцию. Возможно ли это реализовать, или мне лучше повторить свой код?

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
}

person Jans Mans    schedule 09.09.2017    source источник


Ответы (1)


Пусть ваши контроллеры реализуют интерфейс, в котором есть ваша extractID функция. Затем реализуйте это extractID для каждого из ваших контроллеров. Примерно так:

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()
}

Примечание printData принимает IDInterface, но в main я просто передаю контроллер.

person Dan 0    schedule 10.09.2017