在GORM库中省略空的嵌入结构体。

huangapple go评论112阅读模式
英文:

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)
}

https://go.dev/play/p/K905LVhCff6

huangapple
  • 本文由 发表于 2022年12月7日 04:57:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/74708965.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定