Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose models scheme in separate modul

Disclaimer: I am new to mongoose/node, so please excuse me if I am misunderstanding some basic things. Yes, I found already a few postings about this topic, but could not adapt it to my needs.

I structured my main-project into multiple separate projects. One separation is the "app-core" project, which will contain the core-models and -modules, to be injected by each other project (app-core is configured as dependency in the package.json file of each project).

A (simplified) model within the app-core currently looks like this:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var IndustrySchema = new Schema({
name: {
    type: String,
    required: true
}
}); 

module.exports = mongoose.model('Industry', IndustrySchema);

The wep-app includes this model as follow:

var Industry = require('app-core/models/Industry');

and creates the MongoDB connection like this:

var DB_URL = 'mongodb://localhost/hellowins';
var mongoose = require('mongoose');
var mongooseClient = mongoose.connect(DB_URL);
mongooseClient.connection.on('connected',function () {
  console.log("MongoDB is connected");
});

Now I have the problem, that the model will not use the mongo connection that is defined in the app-web project, rather it will consider the connection configured in the app-core.

Due to encapsulation and responsibility design I definitly don't want the core to define the connections for each possible app (which may include the core-app). So somehow I need to specify the the scheme only in the core.

I read already that I should not require the model itself (/app-core/models/Industry), and use the mongoose model instead

var Industry = mongoose.model("Industry");

But then I get the error

MissingSchemaError: Schema hasn't been registered for model "Test"

To fix this, I should register the models manually, like adviced in the first link (at the top of my posting). But somehow I don't like this approach, because I'd need to extend this everytime the application uses a new model.

And further I need a mongo connection even in the core-app - at least to run the mocha tests.

So I am bit confused about how to structure the architecture in this case.

UPDATE #1

I found now one working solution. But, unfortunately, this does not fit my requirements completely, because it is pretty difficult (resp. ugly) to extend a model by hooks (ie TestSchema.pre('save'..)).

Model (app-core)

exports.model = {
    name: {
        type: String,
        required: true
    }
};

models.js (app-web, executed once on startup)

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var models = ['Test']; // add many
exports.initialize = function() {
    var l = models.length;
    for (var i = 0; i < l; i++) {
        var model = require('hw-core/models/' + models[i]);
        var ModelSchema = new Schema(model.model);
        module.exports = mongoose.model(models[i], ModelSchema);
}

};

app.js (web-app)

require('./conf/app_models.js').initialize();

Then I just can get a model as follow

var mongoose = require('mongoose');
var TestModel = mongoose.model("Test");
var Test = new TestModel();
like image 843
Christopher Will Avatar asked Jun 26 '13 10:06

Christopher Will


People also ask

What is the difference between a Mongoose schema and model?

A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.

Which module is internally used by Mongoose?

Mongoose is a Node. js-based Object Data Modeling (ODM) library for MongoDB.

Can Mongoose connect to multiple databases?

Mongoose doesn't allow to use multiple databases in single mongoose instance as the models are build on one connection.


1 Answers

Why don't you try to export the mongoose instance from your app-core module and use it later in the web-app to connect to a database

app-core index.js

var mongoose = require('mongoose');
module.exports = {
    mongooseInstance: mongoose };

web-app index.js

var core = require('app-core'),
    mongoose = core.mongooseInstance,

mongooseClient = mongoose.connect(DB_URL);
// and so on

This might work as long as you require your models in your controllers which are initialized after the code from the index.js. I hope my response is helpful.

like image 79
Tencho Tenev Avatar answered Sep 29 '22 23:09

Tencho Tenev