问题
I have read related post: Cannot overwrite model once compiled Mongoose
Problem is neither of these solution's helped me with my problem.
I get the error in the title and I have following setup:
Folder Structure:
My models look like this:
forums.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const topicGroupSchema = require("./topicGroups");
const forumSchema = new Schema({
title: String,
topicGroups: [topicGroupSchema]
})
const Forum = mongoose.model("forums", forumSchema);
module.exports = Forum;
topicGroups.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const topicGroupSchema = new Schema({
title: String,
// Todo: add topics
})
module.exports = topicGroupSchema;
My test_helper and saveForum_test.js files look like this:
saveForum_test.js
const assert = require("assert");
const Forum = require("../model/forums")
describe("Creating records", () => {
it("can save a new forum", (done) => {
const forum = new Forum({
title: "CodeHUB"
})
forum.save()
.then(() => {
assert(forum.isNew)
done();
})
})
})
test_helper.js
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
before(done => {
mongoose.connect("mongodb://myuser:mypassword@ds221339.mlab.com:21339/clicker", { useNewUrlParser: true });
mongoose.connection
.once("open", () => {done()})
.on("error", error => {
console.warn("error", error)
})
})
// FIXME: error when saved twice
beforeEach(done => {
console.log(mongoose.connection.collections.forums)
mongoose.connection.dropCollection("forums", () => {
done();
})
})
So when I run my test suite with mocha, everything works as expected. But when I change something, and run it again, I get the error
OverwriteModelError: Cannot overwrite
forums
model once compiled.
I use mlab with mongoose and not a local installed mongodb. Maybe it has something todo with that? I can't figure it out, I checked all the files and imports etc. 10 times and can't find a mistake, can you ?
回答1:
I have solved the problem.
Turns out the problem was how I was running my test suite.
My npm run test
command in package.json
did the following:
"test": "mocha --watch"
Here was the error. I think --watch
doesn't reinstantiate everything and is just like "Hot Module Replacement".
I installed nodemon
and changed my test script like this:
"test": "nodemon --exec \"mocha -R min\""
This makes sure to rerun the whole files and no error is showing up.
Another related post that should work: mocha --watch and mongoose models
回答2:
There is another option to solve this and keep using mocha --watch.
Instead of requiring the models, you can use a function like this one, so the model is no overwritten.
function loadModel(modelName, modelSchema) {
return mongoose.models[modelName] // Check if the model exists
? mongoose.model(modelName) // If true, only retrieve it
: mongoose.model(modelName, modelSchema) // If false, define it
}
Imagine you have a model 'User'. You would have to export it using the above function:
const userSchema = {...}
module.exports = () => loadModel('User', userSchema)
Now, when you want to import the model, you do it calling the function:
const User = require('../pathToTheModelLoaderFunction/user.js')()
回答3:
I suggest you to have a simpler approach, which just consists in deleting the model after the test did run.
Here it is:
after(() => {
delete mongoose.connection.models['MyModelName'];
});
You may also add it before all, in order to make sure you are starting all tests with no existing models.
Object.keys(mongoose.connection.models).forEach(modelName => {
delete mongoose.connection.models[modelName]
})
来源:https://stackoverflow.com/questions/53463644/why-do-i-get-error-cannot-overwrite-model-once-compiled-in-mongoose-when-i-run