更新方法不更新零值 [英] Update method does not update zero value
问题描述
原始问题
在GORM中使用 Update
方法时,不会保存新数据.即我想将 bool
从 true
设置为 false
,但是即使在 Update
方法之后,它仍然保持为true.
When using the Update
method in GORM the new data does not get saved. i.e. I want to set a bool
from true
to false
, but it stays true even after the Update
method.
在该方法的说明中有一个警告:警告,当用struct更新时,GORM不会更新值为零的字段"
In the description of the method there is a warning: "WARNING when update with struct, GORM will not update fields that with zero value"
由于我使用结构进行更新并且 false
是 bool
的零值,因此这似乎是预期的行为,但是我看不出为什么要这样做那么,以及如何克服这个问题.
Since I am using a struct to update and false
is the zero value of bool
, this seems expected behaviour, but I don't see any reason why to do so and how to overcome this.
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
关键字.然后,我使用了一个辅助函数(来自此处),用于将结构转换为映射,同时将json别名保留为键:
First, as suggested I left out the new
keyword when instantiating the structs. Then, I used a helper function (from here) for converting a struct to map while keeping the json alias as keys:
// 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
}
然后,我遍历数据切片中的每个元素,以便对其进行转换并一次更新:
Then I loop over each element in the data slice in order to convert it and update it one by one:
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)
}
*在此示例中,错误处理明显减少了.
*Error handling is obviously reduced in this example.
推荐答案
摘自官方 doc
注意使用struct更新时,GORM将仅更新非零值字段,您可能希望使用地图来更新属性或使用选择"指定要更新的字段
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 {}
来更新非零字段.示例:
So use map[string]interface{}
to update non-zero fields also. Example:
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
已经有了结构,您可以将 struct
转换为 map [string] interface {}
(
As you have struct already you can convert struct
into map[string]interface{}
(See details about conversion) then update. Another way is change the type of field as pointer.
这篇关于更新方法不更新零值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!