Your Question
I redefine a type and implement interface driver.Value and driver.Scanner,for instance, I want type []string to be stored as a json string, but I need to update it to null even if it is a nil value.
type Example []string
// Value returns m as driver.Value
func (m Example) Value() (driver.Value, error) {
bin, err := json.Marshal(m)
return string(bin), err
}
func (m *Example) Scan(v interface{}) error {
switch data := v.(type) {
case string:
return json.Unmarshal([]byte(data), m)
case []byte:
return json.Unmarshal(data, m)
default:
return fmt.Errorf("invalid value %v for Example to Scan", v)
}
}
Expected answer
I suggest gorm offer an interface IsZero as a supplement to the method reflect.field.IsZero.
Morever, a field tag nozero、nonil or something like that is also appreciated.
type Outer struct{
Inner Example `gorm: "nozero"`
}
Comment From: jinzhu
Update zero fields https://gorm.io/docs/update.html#Update-Selected-Fields
Comment From: jinzhu
I don't think it is necessary to add another API to do the job, sounds like just a update zero-value fields issue, which is same if you are using other data types like: int, string?
Comment From: sdghchj
I don't think it is necessary to add another API to do the job, sounds like just a update zero-value fields issue, which is same if you are using other data types like:
int,string?
Selecting explicitly actually does work for zero fields, but if my object has many fields, I don't think it is a good experience everytime to select every feild. Everytime I add or remove a field, I have to add or remove it in the select clause.
Comment From: jinzhu
If you want to select all fields, you can use db.Select("*")
Comment From: sdghchj
If you want to select all fields, you can use
db.Select("*")It is pity that usually there is a few fields that need not to update. More offen I use omit.
Comment From: jinzhu
Select("*").Omit("Name", "Age")
Comment From: sdghchj
go Select("*").Omit("Name", "Age")
e, ok
Comment From: jasonhp
go Select("*").Omit("Name", "Age")
It doesn't work. Select("*") still ignores all zero values.
Comment From: bencq
go Select("*").Omit("Name", "Age")It doesn't work. Select("*") still ignores all zero values.
Yes, I also encountered this problem. Select("*") before Update() doesn't work.
Comment From: 0x9ef
I've faced the same trouble.
I guess it would be better to implement smth like gorm:"allowzero" tag. Why? There are 2 approaches to force zero fields. The first is to use a pointer and the second is to convert the structure to a map. These approaches have critical issues in my opinion.
Approach with a pointer: * We may don't want to use a pointer because it allows using nil as a value, in this way we will generate redundant checks for nil
Approach with converting a structure to a map: * It will provide a performance overhead. Because if a structure is too complex, in large production it would create unacceptable overhead costs
But, if we want to update an association with zero-value it will work.
Comment From: enzofoucaud
Any update ?
Select("*") don't work
Comment From: quolpr
@jinzhu sorry, but map interface looks really weird and unsafe. Could we still bring such an option?