force tag to force zero when updates

This commit is contained in:
bingoohuang 2021-06-24 10:20:40 +08:00
parent 8e67a08774
commit 0f2d805740
3 changed files with 21 additions and 7 deletions

View File

@ -401,17 +401,18 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
// create valuer, setter when parse struct // create valuer, setter when parse struct
func (field *Field) setupValuerAndSetter() { func (field *Field) setupValuerAndSetter() {
_, force := field.TagSettings["FORCE"]
// ValueOf // ValueOf
switch { switch {
case len(field.StructField.Index) == 1: case len(field.StructField.Index) == 1:
field.ValueOf = func(value reflect.Value) (interface{}, bool) { field.ValueOf = func(value reflect.Value) (interface{}, bool) {
fieldValue := reflect.Indirect(value).Field(field.StructField.Index[0]) fieldValue := reflect.Indirect(value).Field(field.StructField.Index[0])
return fieldValue.Interface(), fieldValue.IsZero() return fieldValue.Interface(), !force && fieldValue.IsZero()
} }
case len(field.StructField.Index) == 2 && field.StructField.Index[0] >= 0: case len(field.StructField.Index) == 2 && field.StructField.Index[0] >= 0:
field.ValueOf = func(value reflect.Value) (interface{}, bool) { field.ValueOf = func(value reflect.Value) (interface{}, bool) {
fieldValue := reflect.Indirect(value).Field(field.StructField.Index[0]).Field(field.StructField.Index[1]) fieldValue := reflect.Indirect(value).Field(field.StructField.Index[0]).Field(field.StructField.Index[1])
return fieldValue.Interface(), fieldValue.IsZero() return fieldValue.Interface(), !force && fieldValue.IsZero()
} }
default: default:
field.ValueOf = func(value reflect.Value) (interface{}, bool) { field.ValueOf = func(value reflect.Value) (interface{}, bool) {
@ -424,17 +425,17 @@ func (field *Field) setupValuerAndSetter() {
v = v.Field(-idx - 1) v = v.Field(-idx - 1)
if v.Type().Elem().Kind() != reflect.Struct { if v.Type().Elem().Kind() != reflect.Struct {
return nil, true return nil, !force
} }
if !v.IsNil() { if !v.IsNil() {
v = v.Elem() v = v.Elem()
} else { } else {
return nil, true return nil, !force
} }
} }
} }
return v.Interface(), v.IsZero() return v.Interface(), !force && v.IsZero()
} }
} }

View File

@ -13,6 +13,18 @@ import (
. "gorm.io/gorm/utils/tests" . "gorm.io/gorm/utils/tests"
) )
func TestUpdateZero(t *testing.T) {
c := &Company{
ID: 0,
Name: "bingoo",
Foreign: true,
}
DB.Create(c)
c.Foreign = false
DB.Updates(c)
}
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
var ( var (
users = []*User{ users = []*User{

View File

@ -52,6 +52,7 @@ type Toy struct {
type Company struct { type Company struct {
ID int ID int
Name string Name string
Foreign bool `gorm:"force"`
} }
type Language struct { type Language struct {