英文:
Omit empty embedded struct in GORM library
问题
我在我的项目(REST API)中使用GORM作为ORM库。
一个书籍有一个作者。当没有定义作者(没有名字或姓氏)时,我希望省略完整的作者字段。
现在,“作者”字段的JSON输出是"author": {},
而不是省略该字段。
有什么干净的解决方案可以实现这一点?
代码片段
type Author struct {
FirstName string `json:"first_name,omitempty"`
LastName int32 `json:"last_name,omitempty"`
}
type Book struct {
ID uint
Title string `gorm:"index;not null" json:"title"`
Author Author `gorm:"embedded" json:"author,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
英文:
I use GORM as ORM library for my project (REST API).
A single book has an author. When no author is defined (no first name or last name), I want to omit the complete author field.
Now, the JSON output of the "author" field is "author": {},
instead of omitting the field.
What could be a clean solution to achieve this?
Code snippet
type Author struct {
FirstName string `json:"first_name,omitempty"`
LastName int32 `json:"last_name,omitempty"`
}
type Book struct {
ID uint
Title string `gorm:"index;not null" json:"title"`
Author Author `gorm:"embedded" json:"author,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
答案1
得分: 1
由于看起来 GORM 将始终填充嵌入的结构体,我不确定将其更改为指针是否有效(尽管这可能是一个不错的首次尝试)。
假设不起作用,你可以创建基本上两个版本的结构体,并在编码为 JSON 时切换到使用指针的版本,并在为空时省略:
type book struct {
ID uint
Title string `gorm:"index;not null" json:"title"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Book struct {
book
Author Author `gorm:"embedded" json:"-"`
}
type JSONBook struct {
book
Author *Author `json:"author,omitempty"`
}
func (b Book) MarshalJSON() ([]byte, error) {
jb := JSONBook{book: b.book}
if b.Author.FirstName != "" || b.Author.LastName != "" {
jb.Author = &b.Author
}
return json.Marshal(jb)
}
你可以在这里查看示例代码:https://go.dev/play/p/K905LVhCff6
英文:
Since it looks like GORM will (always populate an embedded struct)(https://github.com/go-gorm/gorm/issues/5431), I don't know that changing it to a pointer will work (although that would be a good first attempt, it might).
Assuming it doesn't, you can create basically two versions of the struct, and switch to the one which uses a pointer when encoding to json, and omit if empty:
type book struct {
ID uint
Title string `gorm:"index;not null" json:"title"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Book struct {
book
Author Author `gorm:"embedded" json:"-"`
}
type JSONBook struct {
book
Author *Author `json:"author,omitempty"`
}
func (b Book) MarshalJSON() ([]byte, error) {
jb := JSONBook{book: b.book}
if b.Author.FirstName != "" || b.Author.LastName != 0 {
jb.Author = &b.Author
}
return json.Marshal(jb)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论