title: this.find(...) never reaches callback within static method
body: <p>I am working on a module which adds Friendship-based relationships to a Schema. </p>
  
  <p>I'm basically trying to do what <a href="https://stackoverflow.com/questions/27335431/call-to-a-static-method-to-a-schema-inside-a-plugin-in-mongoose?rq=1" title="this guy">this guy</a> is trying to do (which, AFAIK, should work--which is discouraging)</p>
  
  <p>Why is <code>find(...)</code> in <code>FriendshipSchema.statics.getFriends</code> never reaching its callback? </p>
  
  <p><strong>EDIT</strong> - Please allow me to explain the expected execution flow...</p>
  
  <p>inside <code>accounts.js</code>:</p>
  
  <ol>
  <li>requires the 'friends-of-friends' module (loads <code>friends-of-friends/index.js</code>) which
  
  <ol>
  <li>requires <code>friends-of-friends/friendship.js</code> which exports a function that creates <code>FriendshipSchema</code>, adds static methods, returns <code>Friendship</code> Model.</li>
  <li>requires <code>friends-of-friends/plugin.js</code> which exports the mongoose plugin that adds static and instance methods to `AccountSchema.</li>
  </ol></li>
  <li>uses <code>FriendsOfFriends.plugin</code> (see <code>friends-of-friends/index.js</code>) to plug-in the functionality from <code>friends-of-friends/plugin.js</code></li>
  <li>defines <code>AccountSchema.statics.search</code> which calls <code>this.getFriends</code>.<br>
  Since <code>this</code> refers to the <code>Account</code> model once it is compiled, and since the plugin added <code>schema.statics.getFriends</code>, calling <code>this.getFriends</code> within <code>AccountSchema.statics.search</code> will call <code>schema.statics.getFriends</code> as defined in <code>friends-of-friends/plugin.js</code>, which will call <code>Friendship.getFriends</code> (defined by <code>FriendshipSchema.statics.getFriends</code> in <code>friends-of-friends/friendship.js</code>) which calls <code>this.find(...)</code> which should translate to Friendship.find(...)`</li>
  <li>after retrieving an account document, I call <code>account.search('foo', function (...) {...});</code>, but as you can see in <code>FriendshipSchema.statics.getFriends</code>, the <code>find</code> method executes, but its callback is never invoked and the program hangs :(</li>
  </ol>
  
  <p>I don't get any errors, so I know this is a logic problem, but I'm not sure why things are getting hung up where they are... </p>
  
  <p><strong>EDIT</strong> - see my answer below, I also needed to compile the models before I could call <code>find</code> on them.</p>
  
  <p>account.js</p>
  
  <pre><code>var mongoose = require('mongoose'),
      passportLocalMongoose = require('passport-local-mongoose');
  
  var FriendsOfFriends = require('friends-of-friends')();
  
  // define the AccountSchema
  // username, password, etc are added by passportLocalMongoose plugin
  var AccountSchema = new mongoose.Schema({
      created:        { type: Date,       default:    Date.now                    },
      profile: {
          displayName:    { type: String,     required:   true,       unique : true,  index: true     },
          firstName:      { type: String,     required:   true,       trim: true,     index: true     }, 
          lastName:       { type: String,     required:   true,       trim: true,     index: true     }, 
      }
  });
  
  // plugin the FriendsOfFriends plugin to incorporate relationships and privacy
  AccountSchema.plugin(FriendsOfFriends.plugin, FriendsOfFriends.options);
  
  AccountSchema.statics.search = function (userId, term, done) {
      debug('search')
  
      var results = {
              friends: [],
              friendsOfFriends: [],
              nonFriends: []
          },
          self=this;
  
      this.getFriends(userId, function (err, friends) {
  
         // never reaches this callback!
  
      });
  
  };
  
  AccountSchema.methods.search = function (term, done) {
      debug('method:search')
      AccountSchema.statics.search(this._id, term, done);
  };
  
  module.exports = mongoose.model('Account', AccountSchema);
  </code></pre>
  
  <p>friends-of-friends/index.js</p>
  
  <pre><code>/**
   * @author  Jeff Harris
   * @ignore
   */
  
  var debug = require('debug')('friends-of-friends');
      friendship = require('./friendship'),
      plugin = require('./plugin'),
      privacy = require('./privacy'),
      relationships = require('./relationships'),
      utils = require('techjeffharris-utils');
  
  module.exports = function FriendsOfFriends(options) {
  
      if (!(this instanceof FriendsOfFriends)) {
        return new FriendsOfFriends(options);
      } 
  
      var defaults = {
          accountName:    'Account',
          friendshipName: 'Friendship', 
          privacyDefault: privacy.values.NOBODY
      };
  
      this.options = utils.extend(defaults, options);
  
      /**
       * The Friendship model
       * @type {Object}
       * @see  [friendship]{@link module:friendship}
       */
      this.friendship = friendship(this.options);
  
      /**
       * mongoose plugin
       * @type {Function}
       * @see  [plugin]{@link module:plugin}
       */
      this.plugin = plugin;
  
      debug('this.friendship', this.friendship);
  
  };
  </code></pre>
  
  <p>friends-of-friends/friendship.js </p>
  
  <pre><code>var debug = require('debug')('friends-of-friends:friendship'),
      mongoose = require('mongoose'),
      privacy = require('./privacy'),
      relationships = require('./relationships'),
      utils = require('techjeffharris-utils');
  
  module.exports = function friendshipInit(options) {
  
      var defaults = {
          accountName:    'Account',
          friendshipName: 'Friendship',
          privacyDefault: privacy.values.NOBODY
      };
  
      options = utils.extend(defaults, options);
  
      debug('options', options);
  
      var ObjectId = mongoose.Schema.Types.ObjectId;
  
      var FriendshipSchema = new mongoose.Schema({
          requester: { type: ObjectId, ref: options.accountName, required: true, index: true },
          requested: { type: ObjectId, ref: options.accountName, required: true, index: true },
          status: { type: String, default: 'Pending', index: true},
          dateSent: { type: Date, default: Date.now, index: true },
          dateAccepted: { type: Date, required: false, index: true }
      });
  
      ...
  
      FriendshipSchema.statics.getFriends = function (accountId, done) {
          debug('getFriends')
  
          var model = mongoose.model(options.friendshipName, schema),
              friendIds = [];
  
          var conditions = { 
              '$or': [
                  { requester: accountId },
                  { requested: accountId }
              ],
              status: 'Accepted'
          };
  
          debug('conditions', conditions);
  
          model.find(conditions, function (err, friendships) {
              debug('this callback is never reached!');
  
              if (err) {
                  done(err);
              } else { 
                  debug('friendships', friendships);
  
                  friendships.forEach(function (friendship) {
                      debug('friendship', friendship);
  
                      if (accountId.equals(friendship.requester)) {
                          friendIds.push(friendship.requested);
                      } else {
                          friendIds.push(friendship.requester);
                      }
  
                  });
  
                  debug('friendIds', friendIds);
  
                  done(null, friendIds);
              }
  
          });
  
          debug('though the find operation is executed...');
      };
  
      ...
  
      return mongoose.model(options.friendshipName, FriendshipSchema);
  };
  </code></pre>
  
  <p>friends-of-friends/plugin.js</p>
  
  <pre><code>var debug = require('debug')('friends-of-friends:plugin'),
      mongoose = require('mongoose'),
      privacy = require('./privacy'),
      relationships = require('./relationships'),
      utils = require('techjeffharris-utils');
  
  module.exports = function friendshipPlugin (schema, options) {
  
      var defaults = {
          accountName:    'Account',
          friendshipName: 'Friendship',
          privacyDefault: privacy.values.NOBODY
      };
  
      options = utils.extend(defaults, options);
  
      var Friendship = mongoose.model(options.friendshipName);
  
      ...
  
      schema.statics.getFriends = function (accountId, done) {
          debug('getFriends')
  
          var model = mongoose.model(options.accountName, schema);
  
          var select = '_id created email privacy profile';
  
          Friendship.getFriends(accountId, function (err, friendIds) {
              if (err) {
                  done(err);
              } else {
                  model.find({ '_id' : { '$in': friendIds } }, select, done);
              }
          });
      };
  
      ...
  
      schema.methods.getFriends = function (done) {
          schema.statics.getFriends(this._id, done);
      };
  };
  </code></pre>