feat: add handling for the interface field, when an Interface field is an object that has already been instantiated, use the type of the instantiated object itself instead of interface{}.

This commit is contained in:
Jinlong Chen 2023-05-02 09:34:28 +08:00
parent aeb298635b
commit 9c2c0d2414
2 changed files with 15 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import (
"time" "time"
"github.com/jinzhu/now" "github.com/jinzhu/now"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"gorm.io/gorm/utils" "gorm.io/gorm/utils"
) )
@ -122,6 +123,16 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
AutoIncrementIncrement: 1, AutoIncrementIncrement: 1,
} }
if field.IndirectFieldType.Kind() == reflect.Interface {
f := schema.ModelValue.FieldByName(fieldStruct.Name)
if f.IsValid() {
e := f.Elem()
if e.IsValid() {
field.IndirectFieldType = e.Type()
}
}
}
for field.IndirectFieldType.Kind() == reflect.Ptr { for field.IndirectFieldType.Kind() == reflect.Ptr {
field.IndirectFieldType = field.IndirectFieldType.Elem() field.IndirectFieldType = field.IndirectFieldType.Elem()
} }

View File

@ -18,6 +18,7 @@ var ErrUnsupportedDataType = errors.New("unsupported data type")
type Schema struct { type Schema struct {
Name string Name string
ModelValue reflect.Value
ModelType reflect.Type ModelType reflect.Type
Table string Table string
PrioritizedPrimaryField *Field PrioritizedPrimaryField *Field
@ -113,6 +114,8 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
if value.Kind() == reflect.Ptr && value.IsNil() { if value.Kind() == reflect.Ptr && value.IsNil() {
value = reflect.New(value.Type().Elem()) value = reflect.New(value.Type().Elem())
} }
modelValue := reflect.Indirect(value)
modelType := reflect.Indirect(value).Type() modelType := reflect.Indirect(value).Type()
if modelType.Kind() == reflect.Interface { if modelType.Kind() == reflect.Interface {
@ -147,7 +150,6 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
return s, s.err return s, s.err
} }
modelValue := reflect.New(modelType)
tableName := namer.TableName(modelType.Name()) tableName := namer.TableName(modelType.Name())
if tabler, ok := modelValue.Interface().(Tabler); ok { if tabler, ok := modelValue.Interface().(Tabler); ok {
tableName = tabler.TableName() tableName = tabler.TableName()
@ -164,6 +166,7 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
schema := &Schema{ schema := &Schema{
Name: modelType.Name(), Name: modelType.Name(),
ModelValue: modelValue,
ModelType: modelType, ModelType: modelType,
Table: tableName, Table: tableName,
FieldsByName: map[string]*Field{}, FieldsByName: map[string]*Field{},