简体   繁体   English

使用 golang、gin 和 gorm 以及 email 等 postgres 进行验证已经存在于数据库中

[英]Validation using golang, gin and gorm with postgres like email already exist in database

在此处输入图像描述 I have something like this and I would like to check if email already exist in DB:我有这样的事情,我想检查 DB 中是否已经存在 email:

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.有了这段代码,每次都在告诉我:Email 已经存在,只适用于第一次。

plase read the document: https://gorm.io/docs/query.html请阅读文档: https://gorm.io/docs/query.html

var userFind models.User
database.DB.Where("email = ?", user.Email).First(&userFind)

Since, your struct object is not a slice.因为,您的结构 object 不是切片。 You should use ErrRecordNotFound .您应该使用ErrRecordNotFound

Note: ErrRecordNotFound only works with First , Last , Take which is expected to return some result.注意: ErrRecordNotFound仅适用于FirstLastTake预计会返回一些结果。 And RecordNotFound is removed in V2.并且RecordNotFound在 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.如果你想避免ErrRecordNotFound错误,你可以像db.Limit(1).Find(&user),一样使用FindFind方法接受结构和切片数据。 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为了更好地理解,请参阅此处的链接: https://gorm.io/docs/v2_release_note.html#ErrRecordNotFoundhttps://gorm.io/docs/query.ZFC35FDC70D5FC69D2569883

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.而且,如果您想在 DB 中添加记录,尽管 email 存在,那么您应该删除唯一约束并在创建记录时检查错误。 If record successfully created then return success response else return the appropriate error message.如果成功创建记录,则返回成功响应,否则返回相应的错误消息。

  1. you should validate the input after binding and before db queries您应该在绑定之后和数据库查询之前验证输入
  2. alter your email column to be unique将您的 email 列更改为唯一
  3. try to insert the validated data to db尝试将经过验证的数据插入到 db
    • if success => 200 (there was no similar email)如果成功 => 200(没有类似的电子邮件)
    • if err => check err code if err => 检查错误码

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有关更多信息,您应该查看GoDoc pg lib可能的错误代码
and then, then you can return a suitable error code然后,然后您可以返回一个合适的错误代码

btw.顺便提一句。 hopefully you don't save clear passwords to db:D希望您不要将清晰的密码保存到 db:D

ITS FINALLY WORKING !它终于工作了! Thanks for everyone thats answered !谢谢大家回答!

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM