Question

I have a decent size project and I need to do a little restructuring.

I am using mongoose as my ORM for node. I would like to put all my mongoose models in a folder called 'models'. I have read that when I do that I can put an index.js file in the models folder such that is will pull in all models and store them.

app.js:

...
var mongoose = require('mongoose');
var models = require('./models')(mongoose);

app.configure(function () {
  mongoose.connect(dbPath, function(err) {
    if (err) throw err;
  });
  ...
});

// include models in my routes so I need access
...

I am getting stuck on exactly what I need to do in the index.js to return all my models

index.js (this is what I have tried, not even close)

function Models(mongoose) {
    var Counters = require('./counters')(mongoose);
    var User = require('./user')(mongoose);
    var Token = require('./token')(mongoose);
    var Team = require('./team')(mongoose);
    var Role =  require('./role')();
    var Layer = require('./layer')(mongoose, counters);
    var Feature = require('./feature')(mongoose, counters, async);


}

module.exports = Models;

Also should I pass in mongoose from the app.js since I needed there to connect to mongo? I.E. I can require it again in the index.js but I am not sure if requiring the same module in different files is bad practice.

EDIT: (here is on of my models)

Sorry forgot to mention that I add 'accessor' type functions in my model classes. I.E. I would like to present a public interface for each model.

user.js:

module.exports = function(mongoose) {

  // Creates a new Mongoose Schema object
  var Schema = mongoose.Schema; 

  // Collection to hold users
  var UserSchema = new Schema({
      username: { type: String, required: true },
      password: { type: String, required: true },
    },{ 
      versionKey: false 
    }
  );

  // Creates the Model for the User Schema
  var User = mongoose.model('User', UserSchema);

  var getUserById = function(id, callback) {
    User.findById(id, callback);
  }

  var getUserByUsername = function(username, callback) {
    var query = {username: username};
    User.findOne(query, callback);
  }


  return {
    getUserById: getUserById,
    getUserByUsername: getUserByUsername
  }
} 
Was it helpful?

Solution

In node.js, modules are cached after the first time they are loaded. So you don't need to pass the mongoose from the app.js.

For example, in models/index.js:

require('./counters')
exports.User = require('./user')
require('./token');
require('./team');
require('./role');
require('./layer');
require('./feature');
// I prefer to use a loop to require all the js files in the folder.

in models/user.js:

var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
  // ... Define your schema here
});

var User = module.exports = mongoose.model('User', userSchema);
module.exports.getUserById = function(id, callback) {
  User.findById(id, callback);
}

module.exports.getUserByUsername = function(username, callback) {
  var query = {username: username};
  User.findOne(query, callback);
}

in app.js:

var mongoose = require('mongoose');
var models = require('./models');

mongoose.connect(dbPath, function(err) {
  if (err) throw err;
});

// Yes! You can use the model defined in the models/user.js directly
var UserModel = mongoose.model('User');

// Or, you can use it this way:
UserModel = models.User;

app.get('/', function(req, res) {
  var user = new UserModel();
  user.name = 'bob';
  user.save();
  // UserModel.getUserByUsername();
  ...
});

Learn more about the modules caching in node.js: http://nodejs.org/api/modules.html#modules_caching

OTHER TIPS

Another very nice approach to call all models in a simple and clean way could be this one:

Project structure:

.   
├── app.js
└── models
    ├── Role.js
    ├── Team.js
    └── User.js

app.js

const fs = require('fs');
const path = require('path');

const modelsPath = path.resolve(__dirname, 'models')
fs.readdirSync(modelsPath).forEach(file => {
  require(modelsPath + '/' + file);
})

Just Create index.js inside models folder and add following code in it

const fs = require("fs");

fs.readdirSync(__dirname).forEach((file) => {
  require("./" + file);
});

now just require("./models"); folder and we are ready to go

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top