登录
首页 >  Golang >  Go问答

在Go语言中使用Gin和Gorm对相同的结构进行创建和更新操作

来源:stackoverflow

时间:2024-03-04 21:39:31 147浏览 收藏

亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《在Go语言中使用Gin和Gorm对相同的结构进行创建和更新操作》很感兴趣。本篇文章就来给大家详细解析一下,主要介绍一下,希望所有认真读完的童鞋们,都有实质性的提高。

问题内容

免责声明:这里是 lang noob

我的用户结构为

type user struct {
    id        uint32    `json:"id"`
    firstname string    `json:"firstname" binding:"required"`
    lastname  string    `json:"lastname"`
    email     string    `json:"email" binding:"required,email,uniquemodelvalue=users email"`
    active    bool      `json:"active"`
    password  string    `json:"password,omitempty" binding:"required,gte=8"`
    usertype  string    `json:"usertype" binding:"oneof=admin backoffice principal staff parent student"`
    createdat time.time `json:"createdat"`
    updatedat time.time `json:"updatedat"`
}

/post /users 处理程序

func create(ctx *gin.context) {
    user := models.user{}
    //validate
    if err := ctx.shouldbind(&user); err != nil {
        response.error(ctx, err)
        return

    }
    db, _ := database.getdb()
    db.create(&user)
    // removing password from the response
    user.password = ""
    response.success(ctx, user)
}

我想使用相同的结构创建更新处理程序,有什么方法可以使用相同的结构执行操作吗?

请注意,struct 需要绑定许多字段 firstname、email 等。 更新时,我可能不会传递这些字段

我想出了类似的东西

/put /users/ 处理程序

func Update(ctx *gin.Context) {
    userID := ctx.Param("userId")
    user := models.User{}
    db, _ := database.GetDB()
    if err := db.First(&user, userID).Error; err != nil {
        response.Error(ctx, err)
        return
    }
    updateUser := models.User{}
    if err := ctx.BindJSON(&updateUser); err != nil {
        response.Error(ctx, err)
    }
    //fmt.Printf("%v", updateUser)
    db.Model(&user).Updates(updateUser)
    response.Success(ctx, user)
}

由于缺少所需的验证,这显然会失败,如果我尝试更新,比方说,只是 lastname


解决方案


您可以尝试将这种情况绑定到刚刚从数据库中提取的 user 结构,如下所示:

func update(ctx *gin.context) {
    userid := ctx.param("userid")
    user := models.user{}
    db, _ := database.getdb()
    if err := db.first(&user, userid).error; err != nil {
        response.error(ctx, err)
        return
    }
    if err := ctx.bindjson(&user); err != nil {
        response.error(ctx, err)
    }
    db.model(&user).updates(user)
    response.success(ctx, user)
}

这可能有效,因为旧值+更改(由 bindjson 写入结构中)可能能够通过验证。

一般来说,这种模式不会在 go 中长期为您提供帮助。

将相同的结构用于两个不同的目的:实体模型的表示以及 api 中与模型相关的消息的表示,迟早会给您带来麻烦。这些往往略有不同,例如您最终可能会拥有仅在内部公开的字段,或者正如您遇到的那样,您的验证并不对所有用例都有意义。

对于这个问题,可以帮助您的是创建一个新的结构来表示更新用户消息:

package messages

type updateuser struct {
    firstname string    `json:"firstname"`
    lastname  string    `json:"lastname"`
    ... fields that are updatable with appropriate validation tags
}

func (u *updateuser) tomodel() *model.user {
    return &model.user{
       firstname: u.firstname,
       lastname: u.lastname,
       ...
    }
}

然后使用它来验证您的请求模型,然后将其转换为 model.user 进行更新:

func Update(ctx *gin.Context) {
    userID := ctx.Param("userId")
    user := models.User{}
    db, _ := database.GetDB()
    if err := db.First(&user, userID).Error; err != nil {
        response.Error(ctx, err)
        return
    }
    updateUser := messages.UpdateUser{}
    if err := ctx.BindJSON(&updateUser); err != nil {
        response.Error(ctx, err)
    }
    //fmt.Printf("%v", updateUser)
    db.Model(&user).Updates(updateUser.ToModel())
    response.Success(ctx, user)
}

如果您在项目中使用像 gorm 这样的 orm,建议您对请求和响应使用 viewmodel 结构。因为您的数据库表的结构与您的其余 api 模型大多不同。使用视图模型结构可以更轻松地进行数据绑定和验证。

理论要掌握,实操不能落!以上关于《在Go语言中使用Gin和Gorm对相同的结构进行创建和更新操作》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>