Общая обработка CRUD-действий на Голанге - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь создать представление, которое будет обрабатывать все основные операции CRUD на моих моделях gorm. Цель состоит в том, чтобы передать модель представлению и позволить всей магии случиться.

Я нашел темы об использовании отражений, но я также прочитал, что это не «путь Голанга».

Первая проблема, с которой я столкнулся, это gorm, использующий таблицу «value» всегда. Поэтому временным решением для этого является принудительное использование таблицы «users» или имени таблицы из CommonView

package controllers

import (
    "encoding/json"
    "fmt"
    "github.com/jinzhu/gorm"
    "net/http"
    "reflect"
)

type CommonView struct {
    db        *gorm.DB
    modelType reflect.Type
    model     interface{}
    tableName string
}

func NewCommonView(db *gorm.DB, model interface{}, tableName string) *CommonView {
    return &CommonView{
        db:        db,
        modelType: reflect.TypeOf(model),
        model:     model,
        tableName: tableName,
    }
}

func (cv *CommonView) HandleList(w http.ResponseWriter, r *http.Request) {
    modelSliceReflect := reflect.SliceOf(cv.modelType)
    models := reflect.MakeSlice(modelSliceReflect, 0, 10)

    fmt.Println(modelSliceReflect)
    fmt.Println(models)

    //modelsDirect := reflect.MakeSlice(reflect.TypeOf(cv.model), 0, 0)
    cv.db.Table("users").Find(&models)

    fmt.Println("From db: ")
    fmt.Println(models)

    modelType := reflect.TypeOf(modelSliceReflect)
    fmt.Println("Type name: " + modelType.String())


    modelsJson, _ := json.Marshal(models)

    fmt.Fprint(w, string(modelsJson))
}

Модель: комплектация

import "golang.org/x/crypto/bcrypt"

type User struct {
    Id        string `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"`
    FirstName string `json:"firstName"`
    LastName  string `json:"lastName"`
    Email     string `json:"email" gorm:"unique;not null"`
    Password  string `json:"-"`
}

func (User) TableName() string {
    return "user"
}

Gorm находит строки в БД (это известно из журнала gorm). Но json не бросает их - думаю, что это не тот тип, и он не может с этим справиться. Есть идеи, как справиться с этой проблемой?

Если у вас есть и другие решения, как решить проблему представления CRUD, я также буду очень признателен.

1 Ответ

0 голосов
/ 07 января 2019

Проблема возникает из-за того, что пакет json обрабатывает reflect.Value не так, как ожидалось. Подобное обсуждение можно найти здесь: https://github.com/golang/go/issues/7846

Как видно из следующего фрагмента кода, reflect.MakeSlice возвращает тип Value, а не фрагмент.

slice_empty_reflect_make := reflect.MakeSlice(
                                    reflect.SliceOf(
                                            reflect.TypeOf(5)),
                                    10, 10)

fmt.Printf("Type of reflect.MakeSlice(): %s\n",
           reflect.TypeOf(slice_empty_reflect_make).Name())

Это дает:

Type of reflect.MakeSlice(): Value

Когда вы вводите Value в маршаллере json, он возвращает объект, а не массив:

Json: {}
Error: <nil>

Вам необходимо вернуться к интерфейсу Value, используя .Interface():

jsonBytes, err := json.Marshal(slice_empty_reflect_make.Interface())

И это замаскированный дубликат Как мне сериализовать карту типа [string] refle.Value?

...