When applying updates gorm appears to omit golang 'zero-values' from the update struct. In the case of boolean fields this means true values will update the db record to true as expected, however false values are omitted from the sql statement all-together. The net result is that you can set any boolean value to true, but afterwards you can never set it to false again.
Yes this is a bug https://github.com/jinzhu/gorm/issues/192#issuecomment-52408118
Yes, gorm will ignore zero-values when update struct. and this is what we can't fix ;( (because golang will always initialize all values, so when update with struct, gorm can't know it is setted by you or initialized by golang)
But you could update the value in a different way:
// solution 1
DB.Model(&page).Update("CommentsEnabled", commentsenabled)
// solution 2
page.Commentsenabled = commentsenabled;
DB.Save(&page)
// solution 3
DB.Model(&page).Updates(map[string]interface{}{"CommentsEnabled": commentsenabled})
///
I received a pull request from @Bugagazavr to use gorm in my project:
https://github.com/drone/drone
I'm seriously considering accepting his pull request because gorm has a lot of great features that would benefit our project, however, I'd like to discuss this issue a bit further.
I think I understand why this works the way it does. It gives the ability to update only a subset of fields in the database. Unfortunately, this feature leads to unexpected behavior where booleans (or other fields) may not get updated. This means I need to very carefully audit every field and every update statement to avoid potential bugs. One of the benefits of an ORM should be that I don't need to think about these things.
If you look at meddler, for example, they update every single field, every single time. As a result, they provide a very predictable behavior which results in less bugs.
@jinzhu what if I don't want to selectively update fields? Would it be possible to control this behavior via some sort of setting? Or perhaps you could add an additional DB.SaveAll(&user) method that doesn't ignore default primitive values?
This looks like a great library and I can see a lot of hard work went into it, and I look forward to integrating in our app.
Hello @bradrydzewski
Thank you for considering the use of gorm in your project.
If you don't want to select update fields, you could just save it with DB.Save(&user)
I just quick reviewed the pull request, I think I will give some suggestions ;)
I know this is an old ticket, but has it been solved other than those options mentioned above?
Most helpful comment
Yes, gorm will ignore zero-values when update struct. and this is what we can't fix ;( (because golang will always initialize all values, so when update with struct, gorm can't know it is setted by you or initialized by golang)
But you could update the value in a different way: