Call require on mongoose model more than once

I have models in mongoose defined as follows:

user.js

module.exports = function() {
  var mongoose = require('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
  }
}()

Basically I am returning a public interface that clients of the User model can use. I.E. my routes for users grabs the model and can call the two public methods defined and nothing else. I am doing this to abstract the fact the I am using mongodb/mongoose from my routes. I will very likely have a User model that talks to postgres as well at some point, or may just switch to postgres. As such I don't want to have to look through the code for places in routes methods that called mongoose specific functions.

Here is my problem. Most everywhere in the code when I need a module I call

var someUtil = require('./someUtil');

However if I do that more than once for a mongoose model I get an error stating that it cannot be defined twice.

var User = require('./user');  // Cannot put this in more than one file without getting an error.

Is there a better way to code the user.js file such that I can provide a public interface to my User model but only define the Schema once so that I can call require more than one time on that file?

You should separate the Mongoose model from the service you wrap it with.

I'd suggest you have a models folder, with 1 file per schema, each file will look a bit like this:

'use strict';

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

var User = new Schema({
    ...fields your schema will have
})

//additional virtuals or configuration

module.exports = mongoose.model('User', User)

then have a services folder with a UserService that requires that model:

var User = require('../models/User')

function UserService(){
    //create User, delete User, etc.
}

module.exports = new UserService()

then from now on in your controllers or routes just require the UserService. You won't have this kind of problems and your code is better organized.

I have run into this issue as well.

Something you can do is wrap the schema definition in a try catch

Replace this line var User = mongoose.model('User', UserSchema); with:

var User;
try {
  User = mongoose.model('User', UserSchema);
}
catch(e) {
  User = mongoose.model('User');
}

Not sure if its the best way but it will work.

Andreas is correct:

AFAIK node caches the result of requireing a module, and thus the above function should not be run twice. Other than that there's no reason to wrap you code in a self-executing function, just expose the methods like exports.getUserById = getUserById; //etc.

I've run into this problem and I thought I would contribute my answer. The issue I have is slightly more complicated because I have 'ref' definitions in my schemas. I haven't quite got to the bottom of the "why" but basically what's happening is somehow the dependency chain is causing node to require the same file twice. This is verified, as I get the console.log output twice. My prior approach had been to simply export the schemas instead of the models, but this got annoying because I had to bootstrap all the models at the start of execution. After some tinkering, I settled on this paradigm (using coffeescript):

Mongoose = require 'mongoose'

unless 'Foo' in Mongoose.modelNames()
  schema = new Mongoose.Schema
    bar: String
  Mongoose.model 'Foo', schema

module.exports = Mongoose.model 'Foo'