【发布时间】:2021-01-27 12:19:38
【问题描述】:
原始问题
在 GORM 中使用 Update 方法时,新数据不会被保存。即我想将bool 从true 设置为false,但即使在Update 方法之后它仍然是正确的。
在方法的描述中有一个警告:“WARNING when update with struct, GORM will not update fields that with zero value”
由于我使用结构进行更新并且false 是bool 的零值,这似乎是预期的行为,但我看不出有任何理由这样做以及如何克服这个问题。
func UpdateData(c *fiber.Ctx) error {
db := database.DBConn
data := new([]entities.Data)
if err := c.BodyParser(&data); err != nil {
return err
}
db.Update(&data)
return c.JSON(data)
}
解决方案总结
首先,正如建议的那样,我在实例化结构时省略了 new 关键字。然后,我使用辅助函数(来自here)将结构转换为映射,同时将 json 别名作为键:
// StructToMap Converts a struct to a map while maintaining the json alias as keys
func StructToMap(obj interface{}) (newMap map[string]interface{}, err error) {
data, err := json.Marshal(obj)
if err != nil {
return
}
err = json.Unmarshal(data, &newMap) // Convert to a map
return
}
然后我循环遍历数据切片中的每个元素,以便对其进行转换并一一更新:
func UpdateData(c *fiber.Ctx) error {
db := database.DBConn
data := []entities.Dard{}
if err := c.BodyParser(&data); err != nil {
return err
}
for _, record := range data {
mappedData, _ := StructToMap(record)
db.Model(&entities.Data{}).Update(mappedData)
}
return c.JSON(data)
}
*在这个例子中,错误处理明显减少了。
【问题讨论】:
-
拒绝投票是故意匿名的。要求解释是不恰当的。
-
反对票是不言自明的。根据定义,它们的意思是“这个问题没有显示任何研究成果;它不清楚或没有用”(将鼠标悬停在向下投票箭头上以查看此内容)。解释反对票的问题已经在 meta 上讨论了数千次。很无聊。
-
为什么是这种行为的问题是要问 GORM 作者。如果将类型更改为指针不适合您,那么我没有想法。但我不是 GORM 用户,所以希望其他人能提供更好的东西。
-
"如何改进问题以获得更好的答案?" that 是寻求反馈的好方法。我没有任何建议。这个问题也只有一个小时的时间,所以我不希望得到很好的答案。
-
尽量避免使用
new。data是*[]entities.Data类型(new是一个内置函数,看起来有点像:new(T) *T)。因此,您将**[]entities.Data传递给BodyParser和Update函数。如果您的目标是创建一个新切片,请编写:data := []entities.Data{}或data := make([]entities.Data, len, cap)。检查所有错误函数也可能返回