我正在使用优惠券表单,其中我有一些可选字段。
简介
所有表单字段值都以JSON格式接收并映射到Golang结构中。在结构中,我为每个字段添加了“omitempty”标志。因此,只有那些具有一些适当值的表单值被映射,其余的值如0,“”,false将被结构忽略。
这是Golang结构
type Coupon struct {
Id int `json:"id,omitempty" bson:"_id,omitempty"`
Name string `json:"name,omitempty" bson:"name,omitempty"`
Code string `json:"code,omitempty" bson:"code,omitempty"`
Description string `json:"description,omitempty" bson:"description,omitempty"`
Status bool `json:"status" bson:"status"`
MaxUsageLimit int `json:"max_usage_limit,omitempty" bson:"max_usage_limit,omitempty"`
SingleUsePerUser bool `json:"single_use_per_user,omitempty" bson:"single_use_per_user,omitempty"`
}
问题:
当我第一次保存此表单时,相应的表单值将保存到Mongodb中。
现在我想更新该表单,并假设有一个复选框,在保存数据时已选中该复选框。更新表单时,将取消选中该复选框,并提交表单进行保存。现在我在结构中应用了“omitempty”标志,因此它不将空值映射到复选框字段。由于该值未映射到结构中,因此不会将其保存到数据库中。
当用户第二次编辑表单时,它会看到与选中相同的复选框。 (但实际上,该值应更新为DB,复选框应显示为未选中。)
我在REST API中使用相同的表单数据(JSON格式)。在API中,在更新表单数据时,如果我只提到那些需要的值并且不传递我不想更新的值,那么MongoDB会使用提供的所需值覆盖整个文档(即使这些值是也被覆盖,我不想更新,也不传递API)。
要求:
将来,我想公开REST API,所以我不希望这件事发生在那里。这就是为什么我不想从结构字段中删除“omitempty”标志。
在结构中使用omitempty标志时,有没有办法将空表单值或API数据字段保存到数据库?
谢谢!
答案 0 :(得分:3)
值bool
类型有两个可能的值:false
和true
。并且您希望使用bool
字段“通信”3个不同的状态,即不更新字段,将字段设置为false
并将字段设置为true
。这显然是不可能的。
同样适用于int
值:0
的值不能代表2种不同的选择,即不更新字段并将其设置为0
。
如果您想在标记值中保留omitempty
选项,那么为了使其有效,您必须将字段更改为指针:
type Coupon struct {
Id *int `json:"id,omitempty" bson:"_id,omitempty"`
Name string `json:"name,omitempty" bson:"name,omitempty"`
Code string `json:"code,omitempty" bson:"code,omitempty"`
Description string `json:"description,omitempty" bson:"description,omitempty"`
Status *bool `json:"status" bson:"status"`
MaxUsageLimit *int `json:"max_usage_limit,omitempty" bson:"max_usage_limit,omitempty"`
SingleUsePerUser *bool `json:"single_use_per_user,omitempty" bson:"single_use_per_user,omitempty"`
}
它的工作方式是,如果指针是nil
,它将被省略(这是“omitempty”选项)。如果该字段是非nil
指针,则它将更新为指向的值。
例如,如果您要排除bool
字段,则*bool
值应为/ nil
。如果要将其设置/更新为false
,则它必须是指向false
值的指针。如果要将其设置/更新为true
,则它必须是指向true
值的指针。
一般情况下,任何zero value都可以并且应该被计算的类型,如果你把它作为一个指针,你只能处理“它是零值”和“它从输入中丢失” ,并且指针的nil
值将表示“从输入中丢失”的情况,而指向零值的非nil
指针将表示“它是零值”的情况。因此,在上面的示例中,如果string
字段也可以采用空字符串值(""
),那么您还必须使它们成为指针。
请注意,您也可以使用自定义编组和解组逻辑来实现此目的,但这更麻烦,使用指针会自动为您提供此功能。
答案 1 :(得分:0)
您应该使用指针使用omitempty,如下所示
type Coupon struct {
Id int `json:"id,omitempty" bson:"_id,omitempty"`
Name string `json:"name,omitempty" bson:"name,omitempty"`
Code *string `json:"code,omitempty" bson:"code,omitempty"`
Description string `json:"description,omitempty" bson:"description,omitempty"`
Status *bool `json:"status" bson:"status"`
MaxUsageLimit int `json:"max_usage_limit,omitempty" bson:"max_usage_limit,omitempty"`
SingleUsePerUser bool `json:"single_use_per_user,omitempty" bson:"single_use_per_user,omitempty"`
}
有一篇很好的文章可以解释积分如何运作https://willnorris.com/2014/05/go-rest-apis-and-pointers