无法覆盖已编译的`users`模型,Node.js

6
我在编译代码时遇到了这个错误。
throw new mongoose.Error.OverwriteModelError(name);
      ^
OverwriteModelError: Cannot overwrite `users` model once compiled.

这是我的 Model/users.js 文件

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config = require('../config/database');

//User Schema
const UserSchema = mongoose.Schema({
  name: {
    type:String
  },
  email: {
    type:String,
    required:true
  },
  username: {
    type:String,
    required:true
  },
  password: {
    type:String,
    required:true
  }
});

const users = module.exports = mongoose.model('users',UserSchema);

module.exports.getUserById = function(id,callback)
{
  User.findById(id,callback);
}

module.exports.getUserByUsername = function(username,callback){
  const query = {username: username}
  user.findOne(query,callback);
}
module.exports.addUser = function(newUser,callback){
  bcrypt.genSalt(10,(err,salt)=>{
    if(err)
    {
      throw err;
    }
    bcrypt.hash(newUser.password,salt,(err,hash)=>{
      newUser.password=hash;
      newUser.save(callback);
    });
  });
}

这是我的 route/users.js 文件。
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
var Log = require('log')
  , log = new Log('info');

const User = require('../Model/users');
//const ap = express();

//Register router
router.post('/register',(req,res,next)=>{
  log.info('entering register');
  let newUser = new User({
    name:req.body.name,
    email:req.body.email,
    username:req.body.username,
    password:req.body.password
  });
  User.addUser(newUser,(err,user)=>{
    log.info("inside add user");
    if(err){
      log.error('error while registaring ' + err);
      res.json({success:false,msg:'failed to register user'});
    }
    else {
      res.json({sucess:true,msg:'user registered succefully'});
    }
  })
});
router.get('/authenticate',(req,res,next)=>{
  res.send("authenticated");
});
router.get('/profile',(req,res,next)=>{
  res.send('profile');
});
module.exports=router;

passport.js

const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../model/users');
const config = require('../config/database');

module.exports = function(passport){
  let opts = {};
  opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
  opts.secretOrKey = config.secret;
  passport.use(new JwtStrategy(opts,(jwt_payload,done)=>{
    User.getUserById(jwt_payload._id,(err,user)=>{
      if(err)
      {
        return done(err,false);
      }
      if(user){
        return done(null,user);
      }
      else {
        return done(null,false);
      }
    })
  }));
}

我尝试了来自[Cannot overwrite model once compiled Mongoose]的建议,但我无法理解问题所在。

5个回答

11

更新您的`require`语句,使路由和护照文件一致:const User = require('../model/users');大小写敏感!

看起来您没有使用正确的Mongoose术语。根据官方文档,应该如下实现。

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config = require('../config/database');

//User Schema
const UserSchema = mongoose.Schema({
  name: {
    type:String
  },
  email: {
    type:String,
    required:true
  },
  username: {
    type:String,
    required:true
  },
  password: {
    type:String,
    required:true
  }
});

UserSchema.statics.getUserById = function(id,callback)
{
  return this.findById(id,callback);
};

UserSchema.statics.getUserByUsername = function(username,callback){
  const query = {username: username}
  return this.findOne(query,callback);
};
UserSchema.statics.addUser = function(newUser,callback){
  bcrypt.genSalt(10,(err,salt)=>{
    if(err)
    {
      throw err;
    }
    bcrypt.hash(newUser.password,salt,(err,hash)=>{
      newUser.password=hash;
      newUser.save(callback);
    });
  });
};

module.exports = users = mongoose.model('users',UserSchema);;

仍然无法工作,你能否使用你的代码运行它? - user3649361
我刚刚在我做的一个应用程序中测试了我刚提供的代码,它可以正常运行。你的问题可能是代码其他部分引起的吗? - SimplyComplexable
1
@user3649361,我不知道这是否会解决任何问题,但是你的文件中存在不一致的导入:在护照文件中是const User = require('../model/users');,而在路由文件中是const User = require('../Model/users');。这可能会引起问题,所以请更新它。 - SimplyComplexable
哇,它解决了问题,谢谢 :),你可以更新你的答案,我会接受它。 - user3649361
@user3649361 很高兴能够帮到你。我更新了我的答案。 - SimplyComplexable

4
问题在于,你在运行时编译了两次用户信息。
当你执行 users = mongoose.model('users',UserSchema); 时, mongo 将会创建一个名为“users”的集合,所以我认为你又在项目的其它地方再次执行了这个操作。

或者如果你正在使用 fawn,可能你使用了它多次。


2

您希望确保检索模型,如果不存在,则创建该模型。

模型本身也区分大小写。

// user_model.js

const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');

const UserSchema = new mongoose.Schema({
   name: String, 
   email: String
});

UserSchema.methods.generateJWT = function(payload) {
   const options = {expiresIn: "1h"};
   const superHash = Math.random().toString(36).substring(7);
   return jwt.sign({ id: payload }, superHash, options);
}

// *** This fixed my error. ***
// Ensure when creating the model, the name is capitalized like so "User"
module.exports = mongoose.models.Users || mongoose.model("User", UserSchema);

当我创建一个自定义的next.js服务器并从getServerSideProps检索时,我遇到了这个问题。

大小写敏感性在普通的mongoose/express API中从未成为问题。


1
我不能在问题上发表评论,所以我将认为可以解决的信息放在这里。
最可能的问题可能在route/user.js文件中。
 const User = require('../Model/users');

在这里,您正在为用户创建模式,而当您...
let newUser = new User({
    name:req.body.name,
    email:req.body.email,
    username:req.body.username,
    password:req.body.password
});

它试图在其上创建另一个。在model/users.js中也是如此。
module.exports.getUserByUsername = function(username,callback){
  const query = {username: username}
  user.findOne(query,callback);
}

上述user似乎未定义


0

使用一些选项设计您的模式

//User Schema
const UserSchema = mongoose.Schema({
  name: {
    type:String
  },
  email: {
    type:String,
    required:true
  },
  username: {
    type:String,
    required:true
  },
  password: {
    type:String,
    required:true
  }
}, {strict: false});

const users = module.exports = mongoose.model('users',UserSchema);

{strict: false} 是为了未来考虑!如何做到呢?现在您的模式有10个字段,如果将来您想添加一个具有12个(任何多于10个)字段的对象,您可以这样做,因为插入具有这些10个字段的对象没有严格性要求。即使是少于10个字段。

也许这可以解决您的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接