使用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检索到。