2

I'm having trouble with population all of a sudden (was working fine before I updated Mongoose package version). Currently using Mongoose 4.7.6.

var userSchema = require('schemas/user'),
    User = db.model('User', userSchema); // db is already known

User
.findById(user._id) // user is already known due to auth
.populate('group currentPlayer')
.exec(function (findErr, userPlayer) { ... });

If my Schema for User is necessary, I will post it, but currently haven't due to its length (virtuals, methods, statics).

Error:

/app/node_modules/mongoose/lib/model.js:2986
var virtual = modelForCurrentDoc.schema._getVirtual(options.path);
                                            ^
TypeError: modelForCurrentDoc.schema._getVirtual is not a function
    at getModelsMapForPopulate (/app/node_modules/mongoose/lib/model.js:2986:49)
    at populate (/app/node_modules/mongoose/lib/model.js:2660:15)
    at _populate (/app/node_modules/mongoose/lib/model.js:2628:5)
    at Function.Model.populate (/app/node_modules/mongoose/lib/model.js:2588:5)
    at Immediate.<anonymous> (/app/node_modules/mongoose/lib/query.js:1275:17)
...

User Schema

var
Mongoose = require('mongoose'),
Bcrypt   = require('bcrypt'),
ObjectID = Mongoose.Schema.Types.ObjectId,

UserSchema = new Mongoose.Schema({
    active        : { type: Boolean, default: true },
    created       : { type: Date, required: true, default: Date.now },
    modified      : { type: Date, required: true, default: Date.now },
    createdBy     : { type: ObjectID, ref: 'User' },
    modifiedBy    : { type: ObjectID, ref: 'User' },
    email         : { type: String, required: true },
    salt          : { type: String },
    hash          : { type: String },
    session       : String,

    group         : { type: ObjectID, ref: 'Group', required: true },
    currentPlayer : { type: ObjectID, ref: 'Player' },

    validated     : { type: Boolean, default: false },
    ipAddress     : String,
    lastIp        : String,
    notes         : String
});

var _checkPassword = function (password) { ... };

UserSchema.pre('validate', function (next) {
    if (this.password && !_checkPassword(this.password)) {
        this.invalidate('password', 'invalid', "Six character minimum, must contain at least one letter and one number or special character.");
    }
    next();
});
UserSchema.pre('save', function (next) {
    this.modified = Date.now();
    next();
});
UserSchema.virtual('password')
    .get(function () { return this._password; })
    .set(function (passwd) {
        this.salt = Bcrypt.genSaltSync(10);
        this._password = passwd;
        this.hash = Bcrypt.hashSync(passwd, this.salt);
    });

UserSchema.method('verifyPassword', function (password, done) {
    Bcrypt.compare(password, this.hash, done);
});
UserSchema.static('authenticate', function (email, password, done) {
    ...
});

module.exports = UserSchema;
  • Are `group` and `currentPlayer` fields in the user schema and of type `ObjectId` with `ref` to other collections? – Santanu Biswas Jan 13 '17 at 20:38
  • Absolutely. I am going to post the Schema as a response. – conspireagainst Jan 13 '17 at 21:23
  • I was looking at the mongoose code and to me it seems that there is some problem in the `populate` part of your query. May I suggest that you first try by removing the `populate` part from your query and testing. If that works then test by adding `populate` for `group` and `currentPlayer` individually and testing. – Santanu Biswas Jan 13 '17 at 23:32
  • I have already done just that -- removing `populate()` works fine, but population for `group` alone or `currentPlayer` alone does not work either. I also tried a different/simpler `Schema` and model; `populate()` fails there as well. – conspireagainst Jan 14 '17 at 00:31

3 Answers3

2

If anyone comes across this problem, it is probably because you have multiple package.json files with mongoose as a dependency in two of them. Make sure you use one package version of mongoose in your project and register your models there.

bryanph
  • 993
  • 7
  • 18
0

I have now filed a bug on GitHub, since reverting to version 4.6.8 allows my application to work again. https://github.com/Automattic/mongoose/issues/4898

After upgrading to Mongoose v4.7, I now receive an error when populating documents.

The chain of events to reproduce this error:

- define a Schema in its own file and use module.exports on the defined Schema object
- require() the Schema file
- use mongoose.model() to build a model from this Schema
- attempt to retrieve a record by using find() and populate()
- TypeError: modelForCurrentDoc.schema._getVirtual is not a function

If I do NOT use an "external" Schema file, and instead define the Schema inline, the problem goes away. However, this is not tenable due to statics, methods and virtuals defined in many Schemas.

0

Α possible answer can be found here:

The error was raised because I had a field called id that probably was overriding the internal _id field.

Source : https://stackoverflow.com/a/53569877/5683645

Cap Barracudas
  • 2,347
  • 4
  • 23
  • 54