Modeling Mongoose models require models

I have a problem testing Mongolian models

I have a structure like

  • Appendix
    • models
      • Address
      • User
      • Organization
    • test

Both User and Organization models must know the model address. My models are structured as follows:

module.exports = function (mongoose, config) { var organizationSchema = new mongoose.Schema({ name : { type : String }, addresses : { type : [mongoose.model('Address')] } }); var Organization = mongoose.model('Organization', organizationSchema); return Organization; }; 

In my regular application, I require an address before requiring a user and organization, and everything is fine. Now I have written tests for the user and the organization. To register the Address model, I call require('../models/Address.js') This works fine if I run one test. But if I run all the tests in the package, I get an error message because I tried to register the address twice.

OverwriteModelError: Cannot overwrite Address model once compiled.

How to solve this problem?

+6
source share
5 answers

The problem is that you cannot install the mongoose model twice. The easiest way to solve your problem is to use the node.js require function.

Node.js caches all calls to require so that your model does not initialize twice. But you wrap your models with functions. Deploying them will solve your problem:

 var mongoose = require('mongoose'); var config = require('./config'); var organizationSchema = new mongoose.Schema({ name : { type : String }, addresses : { type : [mongoose.model('Address')] } }); module.exports = mongoose.model('Organization', organizationSchema); 

An alternative solution is to make sure that each model is initialized only once. For example, you can initialize all modules before running tests:

 Address = require('../models/Address.js'); User = require('../models/User.js'); Organization = require('../models/Organization.js'); // run your tests using Address, User and Organization 

Or you can add a try catch to your models to handle this special case:

 module.exports = function (mongoose, config) { var organizationSchema = new mongoose.Schema({ name : { type : String }, addresses : { type : [mongoose.model('Address')] } }); try { mongoose.model('Organization', organizationSchema); } catch (error) {} return mongoose.model('Organization'); }; 

Update: In our project, we have a /models/index.js file to handle everything. First, it calls mongoose.connect to establish a connection. Then it requires each model in the models directory and creates a dictionary. So, when we need some kind of model (for example, user ), we require it by calling require('/models').user .

+12
source

Best Solution (IMO):

 try { mongoose.model('config') } catch (_) { mongoose.model('config', schema) } 
+2
source

This question already has an answer, but for a unique way to do this check https://github.com/fbeshears/register_models . This example project uses register_models.js, which includes all models from an array of file names. It works very well, and you end up with all your models pretty much wherever you need them. Keep in mind that node.js cache will cache objects in your project while you work.

+1
source

I use try / catch to solve this problem and it works fine. But I think this is not the best way to do this.

 try{ var blog = mongoose.model('blog', Article); } catch (error) {} 
0
source

I fixed this by fixing r.js and making sure all of my modules use localRequire calls.

Make a request here.

https://github.com/jrburke/requirejs/issues/726

-1
source

All Articles