问题
Original Question
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.
In the description of the method there is a warning: "WARNING when update with struct, GORM will not update fields that with zero value"
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)
}
Solution Summary
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.
回答1:
From official 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
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})
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.
来源:https://stackoverflow.com/questions/64330504/update-method-does-not-update-zero-value