英文:
Validation using golang, gin and gorm with postgres like email already exist in database
问题
我有类似这样的代码,并且我想检查电子邮件是否已经存在于数据库中:
func RegisterUser(c *gin.Context) {
var user models.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": err.Error(),
"data": "",
})
return
}
var existingUser models.User
err := database.DB.Where("email = ?", user.Email).First(&existingUser).Error
if err == nil {
c.JSON(401, gin.H{"message": "Email already exists"})
return
}
if !strings.Contains(user.Email, "@") {
c.JSON(400, gin.H{"message": utils.ErrEmailWrong})
return
}
if len(user.Password) < 4 {
c.JSON(400, gin.H{"message": utils.ErrPasswordLength})
return
}
database.DB.Create(&user)
c.JSON(200, gin.H{
"message": "CREATED",
})
}
在这段代码中,每次都告诉我:Email already exists,只有第一次有效。
英文:
I have something like this and I would like to check if email already exist in DB:
func RegisterUser(c *gin) {
var user models.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"messAge": err.Error(),
"data": "",
})
return
}
// **I TRIED SOEMTHING LIKE THIS**
err := database.DB.Find(&user.Email).Error
if err != nil {
c.JSON(401, gin.H{"MESSAGE": "Email ALREADY exist",
return
}
// **but is not working, because ANY mail it give me error**
if !strings.Contains(user.Email, "@") {
c.JSON(400, gin.H{"MESSAGE": utils.ErrEmailWrong})
return
}
if len(user.Password) < 4 {
c.JSON(400, gin.H{"MESSAGE": utils.ErrPasswordLength})
return
}
database.DB.Create(&user)
c.JSON(200, gin.H{
"MESSAGE": "CREATED",
})
}
With this code, every time is telling me that : Email already exist, only works for the first time.
答案1
得分: 2
请阅读文档:
https://gorm.io/docs/query.html
var userFind models.User
database.DB.Where("email = ?", user.Email).First(&userFind)
英文:
plase read the document:
https://gorm.io/docs/query.html
var userFind models.User
database.DB.Where("email = ?", user.Email).First(&userFind)
答案2
得分: 2
由于您的结构对象不是切片,您应该使用ErrRecordNotFound
。
注意:ErrRecordNotFound
仅适用于First
、Last
、Take
这些预期返回一些结果的方法。在V2中,RecordNotFound
已被移除。
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(401, gin.H{"MESSAGE": "Email Not Found"})
return
}
c.JSON(401, gin.H{"MESSAGE": "Your Message"})
return
}
或者
如果您想避免ErrRecordNotFound
错误,可以使用Find
方法,例如db.Limit(1).Find(&user)
,Find
方法接受结构体和切片数据。然后可以像这样检查:
result.RowsAffected // 返回找到的记录数
为了更好地理解,请参考以下链接:https://gorm.io/docs/v2_release_note.html#ErrRecordNotFound 和 https://gorm.io/docs/query.html
如果您想要在数据库中添加记录,即使电子邮件已存在,您应该删除唯一约束,并在创建记录时检查错误。如果记录成功创建,则返回成功响应,否则返回适当的错误消息。
英文:
Since, your struct object is not a slice. You should use ErrRecordNotFound
.
Note : ErrRecordNotFound
only works with First
, Last
, Take
which is expected to return some result. And RecordNotFound
is removed in V2.
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound){
c.JSON(401, gin.H{"MESSAGE": "Email Not Found",
return
}
c.JSON(401, gin.H{"MESSAGE": "Your Message",
return
}
OR
If you want to avoid the ErrRecordNotFound
error, you could use Find
like db.Limit(1).Find(&user),
the Find
method accepts both struct and slice data. And check like this :
result.RowsAffected // returns count of records found
For better understanding refer the link here : https://gorm.io/docs/v2_release_note.html#ErrRecordNotFound and https://gorm.io/docs/query.html
And, If you want to add record in DB though email exist then you should remove unique constraint and also check the error while creating the record. If record successfully created then return success response else return the appropriate error message.
答案3
得分: 2
- 在绑定数据之后、进行数据库查询之前,应该验证输入。
- 将你的电子邮件列更改为唯一列。
- 尝试将经过验证的数据插入数据库。
- 如果成功 => 返回200(表示没有相似的电子邮件)
- 如果出错 => 检查错误代码
例如:
func IsUniqueContraintViolation(err error) bool {
if pgError, ok := err.(*pgconn.PgError); ok && errors.Is(err, pgError) {
if pgError.Code == "23505" {
return true
}
}
return false
}
要获取更多信息,你可以查看GoDoc pg lib和可能的错误代码,然后返回适当的错误代码。
顺便说一下,希望你不要将明文密码保存到数据库中
英文:
- you should validate the input after binding and before db queries
- alter your email column to be unique
- try to insert the validated data to db
- if success => 200 (there was no similar email)
- if err => check err code
for example:
func IsUniqueContraintViolation(err error) bool {
if pgError, ok := err.(*pgconn.PgError); ok && errors.Is(err, pgError) {
if pgError.Code == "23505" {
return true
}
}
return false
}
For more Information, you should look GoDoc pg lib and Possible Error Codes
and then, then you can return a suitable error code
btw. hopefully you don't save clear passwords to db
答案4
得分: 2
终于成功了!感谢所有回答问题的人!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论