按照beego官网例子写的代码 :
```
type User struct {
Id int
Name string
Profile string
Post []*Post `orm:reverse(many)` //设置一对多的反向关系
}
type Post struct {
Id int
Title string
User *User `orm:rel(pk)` //设置一对多关系
Tags string
}
```
在main中运行程序,初始的时候会报错,如下:
```
field: models.User.Post, unsupport field type [], may be miss setting tag
```
跟了一下源码,错误是在models_utils.go中,getFieldType函数内报的。
```
if ft&IsFieldType == 0 {
err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val)
}
```
完整代码 :
```go
func getFieldType(val reflect.Value) (ft int, err error) {
switch val.Type() {
case reflect.TypeOf(new(int8)):
ft = TypeBitField
case reflect.TypeOf(new(int16)):
ft = TypeSmallIntegerField
case reflect.TypeOf(new(int32)),
reflect.TypeOf(new(int)):
ft = TypeIntegerField
case reflect.TypeOf(new(int64)):
ft = TypeBigIntegerField
case reflect.TypeOf(new(uint8)):
ft = TypePositiveBitField
case reflect.TypeOf(new(uint16)):
ft = TypePositiveSmallIntegerField
case reflect.TypeOf(new(uint32)),
reflect.TypeOf(new(uint)):
ft = TypePositiveIntegerField
case reflect.TypeOf(new(uint64)):
ft = TypePositiveBigIntegerField
case reflect.TypeOf(new(float32)),
reflect.TypeOf(new(float64)):
ft = TypeFloatField
case reflect.TypeOf(new(bool)):
ft = TypeBooleanField
case reflect.TypeOf(new(string)):
ft = TypeVarCharField
case reflect.TypeOf(new(time.Time)):
ft = TypeDateTimeField
default:
elm := reflect.Indirect(val)
fmt.Println("ele.kind:", elm.Kind())
switch elm.Kind() {
case reflect.Int8:
ft = TypeBitField
case reflect.Int16:
ft = TypeSmallIntegerField
//case reflect.Slice: //自己测试填加
// ft = RelReverseMany
case reflect.Int32, reflect.Int:
ft = TypeIntegerField
case reflect.Int64:
ft = TypeBigIntegerField
case reflect.Uint8:
ft = TypePositiveBitField
case reflect.Uint16:
ft = TypePositiveSmallIntegerField
case reflect.Uint32, reflect.Uint:
ft = TypePositiveIntegerField
case reflect.Uint64:
ft = TypePositiveBigIntegerField
case reflect.Float32, reflect.Float64:
ft = TypeFloatField
case reflect.Bool:
ft = TypeBooleanField
case reflect.String:
ft = TypeVarCharField
default:
if elm.Interface() == nil {
panic(fmt.Errorf("%s is nil pointer, may be miss setting tag", val))
}
switch elm.Interface().(type) {
case sql.NullInt64:
ft = TypeBigIntegerField
case sql.NullFloat64:
ft = TypeFloatField
case sql.NullBool:
ft = TypeBooleanField
case sql.NullString:
ft = TypeVarCharField
case time.Time:
ft = TypeDateTimeField
}
}
}
if ft&IsFieldType == 0 {
err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val)
}
```
从完整代码看,没有匹配slice这种类型,所以ft是零,导致报错。于是自己在新加了一个case ,上面代码中注释的两行,添加完后会报零值panic。
```
panic: reflect: call of reflect.Value.Interface on zero Value
```
官网给的例子,以及从网上查阅的资料都是这么写的,可以运行通过, 但是根据源码看确实不支持slice类型。所以如何想要做多对多的关系映射,使用beego框架该如何处理。
请指教,谢谢。
更多评论
一对多关系不应该是外键fk么
type Post struct {
Id int
Title string
User *User `orm:rel(fk)` //设置一对多关系
Tags string
}
多对多关系:
type Post struct {
Id int
Title string
User *User `orm:rel(m2m)` //设置一对多关系
Tags string
}
#1