Вставить данные с помощью Gorm с отражением - PullRequest
0 голосов
/ 13 февраля 2020

Я создаю базовый c REST сервис. Мое намерение состоит в том, чтобы написать логику c для ресурсов как можно более абстрактно. Я имею в виду, что если я уже создал логи CRUD c для конечной точки /devices, например, тогда, когда мне нужна новая конечная точка ресурса, такая как /cars, я не должен повторяться над процедурами CRUD.

На другом языке, таком как Python, классы и методы являются объектами первого класса, которые могут быть сохранены в списке или словаре (карте), а затем созданы при необходимости. В Go это не так просто. Я попытался использовать пакет отражения.

Сначала я создаю TypeRegistry в соответствии с this .

var TypeRegistry = make(map[string]reflect.Type)
TypeRegistry["devices"] = reflect.TypeOf(models.Device{}) // models.Device{} is the Gorm SQL table model

Затем у меня есть создатель обработчика, который предназначен для обработки создания из всех типов ресурсов, подобных этому (обработка ошибок отредактирована):

func CreateOneHandler(typeString string) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        defer r.Body.Close()

        jsn, _ = ioutil.ReadAll(r.Body)
        jsonBytes, _ := datamapper.CreateOne(typeString, jsn)

        w.Write(jsonBytes)
    }
}

Я использую Chi, поэтому привязываю обработчики следующим образом:

func addRoute(r chi.Router, endpoint string, typeString string) {
    r.Route("/"+endpoint, func(r chi.Router) {
        typeString := endpoint
        r.Post("/", CreateOneHandler(typeString))
    })
}

Идея состоит в том, чтобы после определения моделей Gorm просто добавьте маршруты, вызывая их несколько раз, addRoute(r, "devices"); addRoute(r, "cars") для согласованного интерфейса REST для нескольких моделей.

Теперь внутри CreateOne() Я хочу вставить что-то в таблицу:

func CreateOne(typeString string, json []byte) ([]byte, error) {
    modelType := typeregistry.TypeRegistry[typeString]
    value := reflect.New(modelType)
    db.Create(modelPtr.Elem()) // ==> Now this doesn't work 
}

Как мне заставить это работать? Горм сказал: «Не удалось создать такую ​​таблицу: значение». Потому что значение отражения или тип отражения не то же самое, что если бы я просто создавал экземпляры объектов обычным способом. Как мне заставить это работать?

(Примечание: учитывая природу переключателя типов и утверждений типа stati c, я уже ставлю под угрозу некоторые из моих проектов, которые, вероятно, были бы возможны на таких языках, как Python. Мне кажется, что неизбежно засорять код переключателями типов, которые пытались явно проверить, является ли это device, car или любым количеством новых моделей. В обычном объектно-ориентированном языке это может быть быть простым полиморфным вызовом метода c. Любой указатель на лучший дизайн также будет оценен.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...