请问下gorm在定义模型关联时,返回的数据问题

1. 运行环境

go1.18.4 darwin/amd64

2. 问题描述?

G02教程16章,在创建话题成功后,返回了

{
    "code": 200,
    "data": {
        "id": 1,
        "title": "随意生成的标题修改1",
        "content": "随意生成的标题修改,随意生成的标题修改1",
        "user_id": 7,
        "category_id": 1,
        "user": { // 这里返回user字段不全
            "created_at": "0001-01-01 00:00:00",
            "updated_at": "0001-01-01 00:00:00"
        },
        "category": { // 这里返回category字段不全
            "created_at": "0001-01-01 00:00:00",
            "updated_at": "0001-01-01 00:00:00"
        },
        "created_at": "2022-10-08 16:46:45",
        "updated_at": "2022-10-19 18:39:47"
    }
}

请问下gorm在定义模型关联时,返回的数据问题

Model代码

type Topic struct {
    models.BaseModel

    Title      string `json:"title,omitempty"`
    Content    string `json:"content,omitempty"`
    UserID     int64  `json:"user_id,omitempty"`
    CategoryID int64  `json:"category_id,omitempty"`

    User     user.User         `json:"user"`
    Category category.Category `json:"category"`

    models.CommonTimestampsField
}

controller代码

func (ctrl *TopicsController) Store(c *gin.Context) {

    request := requests.TopicRequest{}
    if ok := requests.Validate(c, &request, requests.TopicSave); !ok {
        return
    }

    userModel := auth.User(c)
    cid, _ := strconv.ParseInt(request.CategoryID, 10, 64)
    topicModel := topic.Topic{
        Title:      request.Title,
        Content:    request.Content,
        CategoryID: cid,
        UserID:     userModel.ID,
    }
    topicModel.Create()
    if topicModel.ID > 0 {
        response.Created(c, topicModel)
    } else {
        response.Abort500(c, "创建失败,请稍后尝试~")
    }
}

3. 您期望得到的结果?

正常不是应该返回user/category的全部字段吗?或者不返回,因为没有预加载

请问这个种问题需要怎么处理?
不想去掉关联关系,但是在没有加载的情况下也不想展示无关字段

4. 您实际得到的结果?

请问下gorm在定义模型关联时,返回的数据问题

最佳答案

已经找到解决方案了,是在定义模型时,如果有结构体嵌套(也就是模型关联) 可以将关联的结构体设置成指针类型,包括上边说到的时间类型也设置成指针类型 这样在没有预加载的时候,关联的接口体对应的就是空指针,就会在json解析的时候被过滤掉,前提是需要设置 omitempty 标签

// 模型定义
type Topic struct {
    models.BaseModel

    Title      string `json:"title,omitempty"`
    Content    string `json:"content,omitempty"`
    UserID     int64  `json:"user_id,omitempty"`
    CategoryID int64  `json:"category_id,omitempty"`

    User     *user.User         `json:"user,omitempty"`
    Category *category.Category `json:"category,omitempty"`

    models.CommonTimestampsField
}
// 时间字段
type CommonTimestampsField struct {
    CreatedAt *types.Time `gorm:"column:created_at;index;" json:"created_at,omitempty"`
    UpdatedAt *types.Time `gorm:"column:updated_at;index;" json:"updated_at,omitempty"`
    //DeletedAt time.Time `gorm:"column:deleted_at;index;"json:"deleted_at,omitempty"`
}
1年前 评论
讨论数量: 5

不是返回的字段不全,而是你 Preload 的关联没有数据,并且你在关联的结构体上配置了 json:"fieldName,omitempty"

type Persion struct {
   Id int `json:"id,omitempty`
   Name string  `json:"name,omitempty`
   Age string  `json:"age,omitempty`
   GirlFriend *GirlFriend
}

type GirlFriend struct {
      Persion 
      PersionId int  json:"persionId,omitempty`
      Height int  `json:"height`
}

假设 Persion ( 张三) 没有女朋友

那么 Persion.Preload("GirlFriend") 将会 New 一个初始化的 GirlFriend 里面的所有数据都是 golang 的 "零值"

{
 id: 1,
name : "张三"
girl_friend: {
   height:0,// 注意,因为height 没有 omitempty,所以会返回零值 `0`
   }
}

知识点

golang 结构体上的 json omitempty 选项,在json序列化的时候,如果配置了omitempty,然后这个字段的值是零值,序列化的时候会被舍弃(感官上来说就是字段不见了 :see_no_evil:)

1年前 评论
FatTiger (楼主) 1年前
滚球兽进化 1年前
FatTiger (楼主) 1年前

已经找到解决方案了,是在定义模型时,如果有结构体嵌套(也就是模型关联) 可以将关联的结构体设置成指针类型,包括上边说到的时间类型也设置成指针类型 这样在没有预加载的时候,关联的接口体对应的就是空指针,就会在json解析的时候被过滤掉,前提是需要设置 omitempty 标签

// 模型定义
type Topic struct {
    models.BaseModel

    Title      string `json:"title,omitempty"`
    Content    string `json:"content,omitempty"`
    UserID     int64  `json:"user_id,omitempty"`
    CategoryID int64  `json:"category_id,omitempty"`

    User     *user.User         `json:"user,omitempty"`
    Category *category.Category `json:"category,omitempty"`

    models.CommonTimestampsField
}
// 时间字段
type CommonTimestampsField struct {
    CreatedAt *types.Time `gorm:"column:created_at;index;" json:"created_at,omitempty"`
    UpdatedAt *types.Time `gorm:"column:updated_at;index;" json:"updated_at,omitempty"`
    //DeletedAt time.Time `gorm:"column:deleted_at;index;"json:"deleted_at,omitempty"`
}
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!