Go-Gin以一对多的关系绑定数据



我是Golang和Gin框架的新手,我创建了两个模型

type Product struct {
gorm.Model
Name string
Media []Media
}
type Media struct {
gorm.Model
URI string
ProductID uint
}

和我发送一个POST请求来保存一个新产品,主体是:

{
"name": "Product1",
"media": [
"https://server.com/image1",
"https://server.com/image2",
"https://server.com/image3",
"https://server.com/video1",
"https://server.com/video2"
]
}

我用这个代码

保存一个新产品
product := Product{}
if err := context.ShouldBindJSON(product); err != nil { // <-- here the error
context.String(http.StatusBadRequest, fmt.Sprintf("err: %s", err.Error()))
return
}
tx := DB.Create(&product)
if tx.Error != nil {
context.String(http.StatusBadRequest, fmt.Sprintf("err: %s", tx.Error))
return
}

返回的错误信息是

err: json: cannot unmarshal string into Go struct field Product.Media of type models.Media

我知道ShouldBindJSON不能将media-string转换为media-object,但是这样做的最佳实践是什么?

有效负载与模型不匹配。在JSON主体中,media是一个字符串数组,而在模型中,它是一个具有两个字段和嵌入式表单模型的结构体。

如果你不能改变你当前的设置,在Media上实现UnmarshalJSON,并从原始字节设置URI字段。在同样的方法中,你也可以初始化ProductID为一些东西(如果需要的话)。

func (m *Media) UnmarshalJSON(b []byte) error {
m.URI = string(b)
return nil
}

那么绑定将按预期工作:

product := Product{}
// pass a pointer to product
if err := context.ShouldBindJSON(&product); err != nil {
// handle err ...
return
}
fmt.Println(product) // {Product1 [{"https://server.com/image1" 0} ... }

最新更新