Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用gin和gorm在go lang中对创建和更新操作使用相同的结构_Go_Go Gorm_Go Gin - Fatal编程技术网

使用gin和gorm在go lang中对创建和更新操作使用相同的结构

使用gin和gorm在go lang中对创建和更新操作使用相同的结构,go,go-gorm,go-gin,Go,Go Gorm,Go Gin,免责声明:请点击这里 我的用户结构为 type User struct { ID uint32 `json:"id"` FirstName string `json:"firstName" binding:"required"` LastName string `json:"lastName"` Email string `json:&q

免责声明:请点击这里

我的用户结构为

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)
}
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)
}
我想使用相同的结构创建一个更新处理程序,是否有任何方法可以使用相同的结构执行

请注意,struct在许多字段
firstName、email
等上都需要绑定。 更新时,我可能无法通过这些字段

我想出了类似的办法

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

如果在项目中使用类似Gorm的ORM,建议对请求和响应使用viewmodel结构。因为数据库表的结构与RESTAPI模型的结构大不相同。使用viewmodel结构更容易进行数据绑定和验证。

在这种情况下,您可以尝试绑定到刚刚从数据库中拉出的
用户
结构,如下所示:

func更新(ctx*gin.Context){
userID:=ctx.Param(“userID”)
用户:=模型。用户{}
db,u3;:=database.GetDB()
如果错误:=db.First(&user,userID)。错误;错误!=nil{
响应错误(ctx,err)
返回
}
如果错误:=ctx.BindJSON(&user);错误!=nil{
响应错误(ctx,err)
}
db.Model(&用户)。更新(用户)
响应。成功(ctx,用户)
}
这可能有效,因为旧值+更改(通过
BindJSON
写入结构)可能能够通过验证

一般来说,这种模式对你的长期发展没有帮助

为了两个不同的目的使用相同的结构:实体模型的表示和API中与模型相关的消息的表示,迟早会给您带来麻烦。它们往往略有不同,例如,您可能最终拥有仅在内部公开的字段,或者,正如您所遇到的,您拥有的验证对所有用例都没有意义

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

包消息
类型UpdateUser结构{
FirstName字符串`json:“FirstName”`
LastName字符串`json:“LastName”`
…可使用适当的验证标记进行更新的字段
}
func(u*UpdateUser)ToModel()*model.User{
return&model.User{
名字:美国名字,
姓氏:u.LastName,
...
}
}
然后将其用作验证您的请求模型,然后将其转换为
模型。用户
用于更新:

func更新(ctx*gin.Context){
userID:=ctx.Param(“userID”)
用户:=模型。用户{}
db,u3;:=database.GetDB()
如果错误:=db.First(&user,userID)。错误;错误!=nil{
响应错误(ctx,err)
返回
}
updateUser:=消息。updateUser{}
如果错误:=ctx.BindJSON(&updateUser);错误!=nil{
响应错误(ctx,err)
}
//fmt.Printf(“%v”,updateUser)
db.Model(&user.Updates)(updateUser.ToModel())
响应。成功(ctx,用户)
}
您是否尝试过
BindJSON(&user)
?i、 e.传入表示当前的
user
实例,该实例刚从db user检索到。