更新方法不更新零值
Update method does not update zero value
原题
在 GORM 中使用 Update
方法时,新数据不会被保存。即,我想将 bool
从 true
设置为 false
,但即使在 Update
方法之后它仍然是真实的。
在方法的描述中有一个警告:“警告当使用结构更新时,GORM 将不会更新具有零值的字段”
因为我正在使用一个结构来更新并且 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)
}
*此示例中的错误处理明显减少。
来自官方doc
NOTE When update with struct, GORM will only update non-zero
fields, you might want to use map to update attributes or use Select
to specify fields to update
因此也使用 map[string]interface{}
来更新 non-zero 字段。示例:
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
因为你已经有了结构,你可以将 struct
转换成 map[string]interface{}
(See details about conversion) 然后更新。另一种方法是将字段类型更改为指针。
原题
在 GORM 中使用 Update
方法时,新数据不会被保存。即,我想将 bool
从 true
设置为 false
,但即使在 Update
方法之后它仍然是真实的。
在方法的描述中有一个警告:“警告当使用结构更新时,GORM 将不会更新具有零值的字段”
因为我正在使用一个结构来更新并且 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)
}
*此示例中的错误处理明显减少。
来自官方doc
NOTE When update with struct, GORM will only update non-zero fields, you might want to use map to update attributes or use Select to specify fields to update
因此也使用 map[string]interface{}
来更新 non-zero 字段。示例:
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
因为你已经有了结构,你可以将 struct
转换成 map[string]interface{}
(See details about conversion) 然后更新。另一种方法是将字段类型更改为指针。