16

I don't mean remove a document or documents. I mean remove the model entirely so that mongoose is no longer aware of it. After declaring a model I can't figure out how to make mongoose forget that model so that it could be recreated.

mongoose.model('Book', bookSchema); mongoose.model('Book', bookSchema); 

Currently the above throws an exception.

OverwriteModelError: Cannot overwrite 'Book' model once compiled.

I'd like to be able do something like this...

mongoose.model('Book', bookSchema); mongoose.removeModel('Book'); mongoose.model('Book', bookSchema); 

...and not get any errors. Any ideas?

2
  • 1
    Why would you want to change the model while your program is running? Commented Oct 28, 2013 at 19:30
  • 5
    @EmptyArsenal Clean unit tests without having to destroy and recreate mongoose between each test. Sorry, sometimes I remove context when asking questions because people like to focus on what I'm doing rather than the specific question I asked and that's not always beneficial to me. Commented Oct 28, 2013 at 20:17

4 Answers 4

19

try this

delete mongoose.connection.models['Book']; 

and then re-register/re-initialize it . it will work fine

Sign up to request clarification or add additional context in comments.

1 Comment

Mongoose now has an API for this as the connection.models property is now marked as ReadOnly. Please see this answer: stackoverflow.com/a/71108145/264794
12

It appears that you'd have to overwrite some of the source code in order to be able to remove a model an add a new one since Mongoose makes sure that a model doesn't exist before it's willing to create a new one, which may or may not be more than you care to do:

if (this.models[name] && !collection) { // model exists but we are not subclassing with custom collection if (schema instanceof Schema && schema != this.models[name].schema) { throw new MongooseError.OverwriteModelError(name); } return this.models[name]; } 

Line 587 https://github.com/LearnBoost/mongoose/blob/master/lib/connection.js

Question Author's Update:

Thanks to this answer I discovered that you can access the models defined on the connection through connection.models. In my scenario I was testing a mongoose plugin with Mocha and and I wanted to clear the models between each unit test.

afterEach(function () { mongoose.connection.models = {}; }); 

3 Comments

Thanks to your comment I found that you can just clear it from mongoose.connection.models object that is exposed. Thank you.
If the model exists in mongoose, how do you access it. like for model 'Book' if there is a model in mongoose.connection.model['Book'] then how can i use it. Is it mongoose.model('Book')?
I still got error, can you give me some snippet tutorial?
5

You can use the deleteModel method

mongoose.deleteModel(modelName);

Comments

0

This is actually a better way to get rid of models, schemas and collections in mongoose

mongoose.connections.forEach(connection => { const modelNames = Object.keys(connection.models) modelNames.forEach(modelName => { delete connection.models[modelName] }) const collectionNames = Object.keys(connection.collections) collectionNames.forEach(collectionName => { delete connection.collections[collectionName] }) }) const modelSchemaNames = Object.keys(mongoose.modelSchemas) modelSchemaNames.forEach(modelSchemaName => { delete mongoose.modelSchemas[modelSchemaName] }) 

Reference: https://github.com/Automattic/mongoose/issues/2874#issuecomment-388588452

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.