Mongoose/NextJS-未定义模型/编译后无法覆盖模型 [英] Mongoose/NextJS - Model is not defined / Cannot overwrite model once compiled

查看:70
本文介绍了Mongoose/NextJS-未定义模型/编译后无法覆盖模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个NextJS网站上,该网站在后端使用的是Mongoose和Express.每当我使用signUp函数时,都会在后端收到此错误:

I'm working on a NextJS site which in the backend I'm using Mongoose and Express. Whenever I use signUp function, I get this error on backend:

{"name":"Test","hostname":"DESKTOP-K75DG72","pid":7072,"level":40,"route":"/api/v1/signup","method":"POST","errorMessage":"UserModel is not defined","msg":"","time":"2020-06-17T23:51:34.566Z","v":0}

我怀疑此错误是因为我在其他控制器中使用了UserModel.直到我制作了一个新的控制器,该错误才发生.所以我的问题是,如何解决此问题/如何在不同的控制器/中间件中使用相同的模型?

I suspect this error is because I'm using the UserModel in other controllers. This error wasn't happening until I made a new controller. So my question is, how do I fix this issue/how do I use the same model in different controllers/middlewares?

我认为该问题与 node.js有关-编译后的Mongoose无法覆盖模型这篇文章,我早些时候遇到了这个错误,但是以某种方式设法解决了这个问题.

I think the issue is related to node.js - Cannot overwrite model once compiled Mongoose this post, I was getting this error earlier but somehow managed to fix it.

错误存在于models/User.js中,在预保存中间件中,未在该级别定义UserModel,如何验证用户是否已经使用该用户名存在,如果存在,则拒绝新文档?

controllers/RegisterLogin.js [发生错误的地方]

const UserModel = require("../models/User");
// More packages...

async function signUp(req, res) {
  try {
    const value = await signUpSchema.validateAsync(req.body);
    const response = await axios({
      method: "POST",
      url: "https://hcaptcha.com/siteverify",
      data: qs.stringify({
        response: value.token,
        secret: process.env.HCAPTCHA,
      }),
      headers: {
        "content-type": "application/x-www-form-urlencoded;charset=utf-8",
      },
    });

    if (!response.data.success) {
      throw new Error(errorHandler.errors.HCAPTCHA_EXPIRED);
    }

    const hashPassword = await new Promise((res, rej) => {
      bcrypt.hash(
        value.password,
        parseInt(process.env.SALTNUMBER, 10),
        function (err, hash) {
          if (err) rej(err);
          res(hash);
        }
      );
    });

    await UserModel.create({
      userName: value.username,
      userPassword: hashPassword,
      userBanned: false,
      userType: "regular",
      registeredIP: req.ip || "N/A",
      lastLoginIP: req.ip || "N/A",
    });

    return res.status(200).json({
      success: true,
      details:
        "Your user has been created successfully! Redirecting in 6 seconds",
    });
  } catch (err) {
    const { message } = err;
    if (errorHandler.isUnknownError(message)) {
      logger.warn({
        route: "/api/v1/signup",
        method: "POST",
        errorMessage: message,
      });
    }

    return res.status(200).json({
      success: false,
      details: errorHandler.parseError(message),
    });
  }
}

module.exports = { signUp };

controllers/Profile.js [如果我在此处使用UserModel,它将破坏所有内容]

const UserModel = require("../models/User");
//plus other packages...

async function changePassword(req, res) {
  try {
    const value = await passwordChangeSchema.validateAsync(req.body);

    const username = await new Promise((res, rej) => {
      jwt.verify(value.token, process.env.PRIVATE_JWT, function (err, decoded) {
        if (err) rej(err);
        res(decoded.username);
      });
    });

    const userLookup = await UserModel.find({ userName: username });

    if (userLookup == null || userLookup.length == 0) {
      throw new Error(errorHandler.errors.BAD_TOKEN_PROFILE);
    }

    const userLookupHash = userLookup[0].userPassword;

    try {
      // We wrap this inside a try/catch because the rej() doesnt reach block-level
      await new Promise((res, rej) => {
        bcrypt.compare(value.currentPassword, userLookupHash, function (
          err,
          result
        ) {
          if (err) {
            rej(errorHandler.errors.BAD_CURRENT_PASSWORD);
          }
          if (result == true) {
            res();
          } else {
            rej(errorHandler.errors.BAD_CURRENT_PASSWORD);
          }
        });
      });
    } catch (err) {
      throw new Error(err);
    }

    const hashPassword = await new Promise((res, rej) => {
      bcrypt.hash(
        value.newPassword,
        parseInt(process.env.SALTNUMBER, 10),
        function (err, hash) {
          if (err) rej(err);
          res(hash);
        }
      );
    });

    await UserModel.findOneAndUpdate(
      { userName: username },
      { userPassword: hashPassword }
    );
    return res.status(200).json({
      success: true,
      details: "Your password has been updated successfully",
    });
  } catch (err) {
    const { message } = err;
    if (errorHandler.isUnknownError(message)) {
      logger.warn({
        route: "/api/v1/changepassword",
        method: "POST",
        errorMessage: message,
      });
    }

    return res.status(200).json({
      success: false,
      details: errorHandler.parseError(message),
    });
  }
}

models/User.js

const mongoose = require("mongoose");
const errorHandler = require("../helpers/errorHandler");

const Schema = mongoose.Schema;

const UserSchema = new Schema({
  userName: String,
  userPassword: String,
  userBanned: Boolean,
  userType: String,
  registeredDate: { type: Date, default: Date.now },
  registeredIP: String,
  lastLoginDate: { type: Date, default: Date.now },
  lastLoginIP: String,
});

UserSchema.pre("save", async function () {
  const userExists = await UserModel.find({
    userName: this.get("userName"),
  })
    .lean()
    .exec();
  if (userExists.length > 0) {
    throw new Error(errorHandler.errors.REGISTER_USERNAME_EXISTS);
  }
});

module.exports = mongoose.model("User", UserSchema);

推荐答案

我设法修复了它.这里有两个问题.

I've managed to fix it. There were two problems here.

1)预中间件中不存在"UserModel"变量.通过实例化显然可以解决问题的this.constructor来解决(需要进一步测试)

1) "UserModel" variable doesn't exist in the pre middleware. Solved by instantiating this.constructor which apparently solves the issue (will need further testing)

2)NextJS构建所有东西显然存在问题,似乎每当我使用UserModel中的任何函数时,它都试图创建一个新模型.固定导出已创建的模型

2) There's apparently a issue with NextJS building everything, it seems like it's trying to create a new model whenever I use any function from UserModel. This is fixed exporting the already created model

const mongoose = require("mongoose");
const errorHandler = require("../helpers/errorHandler");

const Schema = mongoose.Schema;

const UserSchema = new Schema({
  userName: String,
  userPassword: String,
  userBanned: Boolean,
  userType: String,
  registeredDate: { type: Date, default: Date.now },
  registeredIP: String,
  lastLoginDate: { type: Date, default: Date.now },
  lastLoginIP: String,
});

UserSchema.pre("save", async function () {
  try {
    const User = this.constructor;
    const userExists = await User.find({
      userName: this.get("userName"),
    })
      .lean()
      .exec();
    if (userExists.length > 0) {
      throw new Error(errorHandler.errors.REGISTER_USERNAME_EXISTS);
    }
  } catch (err) {
    throw new Error(errorHandler.errors.REGISTER_USERNAME_EXISTS);
  }
});

module.exports = mongoose.models.User || mongoose.model("User", UserSchema);

这篇关于Mongoose/NextJS-未定义模型/编译后无法覆盖模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆