在Fiber/MongoDB中重用模型并从响应中删除字段

xu3bshqb  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(104)

我尽量不创建一堵代码墙,如果不需要,也不重新声明代码。
我现在的两个主要问题是:
在第47行,在现有的用户模型userCollection.FindOne(ctx, filter, opts).Decode(&user)上进行了覆盖/解码,但它没有被更新,第46行的选项没有被应用,除非我声明var user2 = models.User,并在第47行解码为user 2,然后在第49行返回user 2
第46行有opts := options.FindOne().SetProjection(bson.M{"password": 0})。如果我使用上面例子中的第二个用户user 2,它在JSON响应中返回密码,但它是null。有没有可能从响应中完全删除密码密钥,而不创建另一个用户模型来在响应中使用它?

func CreateUser(c *fiber.Ctx) error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    var user models.User
 
    //validate the request body
    if err := c.BodyParser(&user); err != nil {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": err.Error()}})
    }
 
    //use the validator library to validate required fields
    if validationErr := validate.Struct(&user); validationErr != nil {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": validationErr.Error()}})
    }
    var email = &user.Email
 
    count, err := userCollection.CountDocuments(ctx, bson.M{"email": email})
    if err != nil {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": "Something went wrong"}})
    }
    if count > 0 {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": "Email already in use"}})
    }
 
    //set the status, hash password, set activate token and updated at
    status := 0
    password := hashPassword(*user.Password)
    activateToken := uuid.New().String()
    updatedAt, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
 
    //create user object
    user.ID = primitive.NewObjectID()
    user.Password = &password
    user.Status = &status
    user.ResetToken = &activateToken
    user.CreatedAt = updatedAt
    user.UpdatedAt = updatedAt
 
    result, err := userCollection.InsertOne(ctx, user)
    if err != nil {
        return c.Status(http.StatusInternalServerError).JSON(responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &fiber.Map{"data": err.Error()}})
    }
 
    //get created user from the DB and cast it into UserResponse model
    filter := bson.M{"_id": result.InsertedID}
    opts := options.FindOne().SetProjection(bson.M{"password": 0})
    userCollection.FindOne(ctx, filter, opts).Decode(&user)
    //return created user
    return c.Status(http.StatusOK).JSON(responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &fiber.Map{"data": user}})
}

我已经尝试创建一个单独的模型UserResponse,不带密码字段,并在CreateUser函数中声明第二个用户模型,以便能够看到FindOne的输出,并在响应中显示选项。

y1aodyip

y1aodyip1#

经过几个小时的计算和发布在这里,我有一个辉煌的时刻。
这里所有的变化是重新声明用户为空的User模型:

user = models.User{} // <- the fix
    filter := bson.M{"_id": result.InsertedID}
    opts := options.FindOne().SetProjection(bson.M{"password": 0})
    userCollection.FindOne(ctx, filter, opts).Decode(&user)

相关问题