最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cannot overwrite `users` model once compiled node js - Stack Overflow

programmeradmin4浏览0评论

I am getting this error while compiling my code

throw new mongoose.Error.OverwriteModelError(name);
      ^
OverwriteModelError: Cannot overwrite `users` model once compiled.

This is my Model/users.js file

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

This is my route/users.js file

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

I have tried suggestion from [Cannot overwrite model once compiled Mongoose but I am not able to understand what the problem is.

I am getting this error while compiling my code

throw new mongoose.Error.OverwriteModelError(name);
      ^
OverwriteModelError: Cannot overwrite `users` model once compiled.

This is my Model/users.js file

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

This is my route/users.js file

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

I have tried suggestion from [Cannot overwrite model once compiled Mongoose but I am not able to understand what the problem is.

Share Improve this question asked Jul 17, 2017 at 17:16 user3649361user3649361 9545 gold badges23 silver badges40 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 11

Update your require statements to be consistent in both the routes and passport file: const User = require('../model/users');. Case does matter!

It looks like you're not using the correct mongoose terminology. Based on their documentation, this should be implemented roughly as follows.

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

The problem is you are compiling User two times in the runtime
once you do users = mongoose.model('users',UserSchema); mongo will create the collection users so i think you are doing it again somewhere in the project

Or if you are working with fawn maybe you are using it more than onetime

You want to ensure you retrieve the model and if its not present, you create the model.

The model itself is also case-sensitive.

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

I ran up on this issue when creating a custom next.js server. Retrieving from the getServerSideProps.

Case-sensitivity was never an issue w/ an ordinary mongoose/express API.

I cant comment onto the question so putting the information i think can resolve is here.

most probably the issue can be on route/user.js file

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

in which you are creating the schema for users,

and when you

let newUser = new User({
    name:req.body.name,
    email:req.body.email,
    username:req.body.username,
    password:req.body.password
});

it tries to create another on top of it.

Also in model/users.js

module.exports.getUserByUsername = function(username,callback){
  const query = {username: username}
  user.findOne(query,callback);
}

above user seems to be undefined

Design your Schema with some options

//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} is for future! How? Now your schema has 10 fields, if in future you want to add an object with 12 (anything more than 10), you can do it, because there is no strictness in inserting objects with these 10 fields. Even if less fields.

May be this may solve your issue

发布评论

评论列表(0)

  1. 暂无评论