编译节点 js 后无法覆盖“用户”模型

Posted

技术标签:

【中文标题】编译节点 js 后无法覆盖“用户”模型【英文标题】:Cannot overwrite `users` model once compiled node js 【发布时间】:2017-12-22 08:03:10 【问题描述】:

我在编译代码时遇到这个错误

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);
    );
  );

这是我的路由/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 的建议 但我无法理解问题所在。

【问题讨论】:

【参考方案1】:

更新您的 require 语句以在路线和护照文件中保持一致:const User = require('../model/users');。案例很重要!

您似乎没有使用正确的猫鼬术语。基于their documentation,大致实现如下。

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,我不知道这是否能解决任何问题,但您的文件中确实存在不一致的导入:护照文件中的const User = require('../model/users'); 和路由文件中的const User = require('../Model/users');。这可能会导致问题,因此请更新。 哇,它解决了这个问题,谢谢:),你可以更新你的答案我会接受的。 @user3649361 很高兴我能提供帮助。我更新了我的答案。【参考方案2】:

问题是您在运行时编译用户两次 一旦你这样做了users = mongoose.model('users',UserSchema); mongo 将创建集合用户,所以我认为你在项目的某个地方再次这样做

或者如果你正在使用小鹿,也许你不止一次使用它

【讨论】:

【参考方案3】:

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

模型本身也区分大小写。

// 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,区分大小写从来都不是问题。

【讨论】:

【参考方案4】:

我无法对这个问题发表评论,所以我认为可以解决的信息就在这里。

很可能问题出在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 以上似乎未定义

【讨论】:

【参考方案5】:

使用一些选项设计您的架构

//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 个字段的对象没有严格要求。即使字段更少。

也许这可以解决你的问题

【讨论】:

以上是关于编译节点 js 后无法覆盖“用户”模型的主要内容,如果未能解决你的问题,请参考以下文章

编译后无法覆盖“用户”模型。解决后我得到“用户”未定义

Mongoose OverwriteModelError:编译后无法覆盖模型

Mongoose OverwriteModelError:编译后无法覆盖模型

一旦编译了模型“”,就无法覆盖“用户”模型(或者我已经监督了一些事情)[重复]

一旦编译了模型“”,就无法覆盖“用户”模型(或者我已经监督了一些事情)[重复]

Mongoose/NextJS - 模型未定义/编译后无法覆盖模型