Cannot overwrite model once compiled Mongoose

2019-01-04 10:12发布

Not Sure what I'm doing wrong, here is my check.js

var db = mongoose.createConnection('localhost', 'event-db');
db.on('error', console.error.bind(console, 'connection error:'));

var a1= db.once('open',function(){
var user = mongoose.model('users',{ 
       name:String,
       email:String,
       password:String,
       phone:Number,
      _enabled:Boolean
     });

user.find({},{},function (err, users) {
    mongoose.connection.close();
    console.log("Username supplied"+username);
    //doSomethingHere })
    });

and here is my insert.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/event-db')

var user = mongoose.model('users',{
     name:String,
     email:String,
     password: String,
     phone:Number,
     _enabled:Boolean
   });

var new_user = new user({
     name:req.body.name,
     email: req.body.email,
     password: req.body.password,
     phone: req.body.phone,
     _enabled:false
   });

new_user.save(function(err){
    if(err) console.log(err); 
   });

Whenever I'm trying to run check.js, I'm getting this error

Cannot overwrite 'users' model once compiled.

I understand that this error comes due to mismatching of Schema, but I cannot see where this is happening ? I'm pretty new to mongoose and nodeJS.

Here is what I'm getting from the client interface of my MongoDB:

MongoDB shell version: 2.4.6 connecting to: test 
> use event-db 
  switched to db event-db 
> db.users.find() 
  { "_id" : ObjectId("52457d8718f83293205aaa95"), 
    "name" : "MyName", 
    "email" : "myemail@me.com", 
    "password" : "myPassword", 
    "phone" : 900001123, 
    "_enable" : true 
  } 
>

17条回答
Anthone
2楼-- · 2019-01-04 10:41

You can easily solve this by doing

delete mongoose.connection.models['users'];
const usersSchema = mongoose.Schema({...});
export default mongoose.model('users', usersSchema);
查看更多
The star\"
3楼-- · 2019-01-04 10:42

I have a situation where I have to create the model dynamically with each request and because of that I received this error, however, what I used to fix it is using deleteModel method like the following:

var contentType = 'Product'

var contentSchema = new mongoose.Schema(schema, virtuals);

var model = mongoose.model(contentType, contentSchema);

mongoose.deleteModel(contentType);

I hope this could help anybody.

查看更多
淡お忘
4楼-- · 2019-01-04 10:43

So Another Reason why You might get this Error is if you use the same model in different files but your require path has a different case. For example in my situation I had:

require('./models/User') in one file and then in another file where I needed access to the User model I had require('./models/user').

I guess the look up for modules & mongoose is treating it as a different file. Once I made sure the case matched in both it was no longer an issue.

查看更多
可以哭但决不认输i
5楼-- · 2019-01-04 10:44

This happened to me when I write like this:

import User from '../myuser/User.js';

However, the true path is '../myUser/User.js'

查看更多
Rolldiameter
6楼-- · 2019-01-04 10:45

I had this issue while unit testing.

The first time you call the model creation function, mongoose stores the model under the key you provide (e.g. 'users'). If you call the model creation function with the same key more than once, mongoose won't let you overwrite the existing model.

You can check if the model already exists in mongoose with:

let users = mongoose.model('users')

This will throw an error if the model does not exist, so you can wrap it in a try/catch in order to either get the model, or create it:

let users
try {
  users = mongoose.model('users')
} catch (error) {
  users = mongoose.model('users', <UsersSchema...>)
}
查看更多
Explosion°爆炸
7楼-- · 2019-01-04 10:47

I know there is an accepted solution but I feel that the current solution results in a lot of boilerplate just so that you can test Models. My solution is essentially to take you model and place it inside of a function resulting in returning the new Model if the Model has not been registered but returning the existing Model if it has.

function getDemo () {
  // Create your Schema
  const DemoSchema = new mongoose.Schema({
    name: String,
    email: String
  }, {
    collection: 'demo'
  })
  // Check to see if the model has been registered with mongoose
  // if it exists return that model
  if (mongoose.models && mongoose.models.Demo) return mongoose.models.Demo
  // if no current model exists register and return new model
  return mongoose.model('Demo', DemoSchema)
}

export const Demo = getDemo()

Opening and closing connections all over the place is frustrating and does not compress well.

This way if I were to require the model two different places or more specifically in my tests I would not get errors and all the correct information is being returned.

查看更多
登录 后发表回答