Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store models in folder, use index.js to require them all

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
  }
} 
like image 484
lostintranslation Avatar asked Jun 22 '13 03:06

lostintranslation


1 Answers

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

like image 82
luin Avatar answered Oct 06 '22 02:10

luin