Search code examples
node.jsmongodbmongoosemongoose-populateodm

Populating Mongoose schema properties with models in external files


Im trying to populate a property inside a Mongoose schema, which references a property in another external model/schema.

I can get the Mongoose population/referencing working when the two models/schemas and the query are all in the same file, but I have my architecture setup so the models are all in their own files within the /models directory, and the /models/index.js will return an object of models (obviously the index.js knows to exclude itself)

The problem I'm running into, is since the Schemas/Models are all in their own files, when I specify the model name as a reference, it doesn't work. I try to load that specific model itself inside the other model, and that also fails.

FYI: Im fairly new to MongoDB and Mongoose, so the following code is very very rough, it's mostly me in the process of learning

Group Model

// models/group.js
'use strict'

module.exports = Mongoose => {
    const Schema = Mongoose.Schema

    const modelSchema = new Schema({
        name: {
            type: String,
            required: true,
            unique: true
        }
    })

    return Mongoose.model( ModelUtils.getModelName(), modelSchema )
}

Account Model

// models/account.js
'use strict'

module.exports = Mongoose => {
    // I tried loading the specific model being referenced, but that doesn't work
    const Group = require('./group')( Mongoose )
    const Schema = Mongoose.Schema

    const modelSchema = new Schema({
        username: {
            type: String,
            required: true,
            unique: true
        },
        _groups: [{
            type: Schema.Types.ObjectId,
            ref: 'Group'
        }]
    })

    // Trying to create a static method that will just return a
    // queried username, with its associated groups
    modelSchema.statics.findByUsername = function( username, cb ) {
        return this
            .findOne({ username : new RegExp( username, 'i' ) })
            .populate('_groups').exec(cb)
    }

    return Mongoose.model( ModelUtils.getModelName(), modelSchema )
}

As you can see in the Account model, Im trying to reference the Group model as the _groups element, and then querying for an account while populating the associated groups inside the modelSchema.statics.findByUsername static method..

Main Application File

// app.js
const models = require('./models')( Mongoose )

models.Account.findByUsername('jdoe', ( err, result ) => {
    console.log('result',result)

    Mongoose.connection.close()
})

Solution

  • I am not clear how the ModelUtils.getModelName() is implemented. I think the issue should be here, because it works well after I changing your codes as below

     // group.js
    return Mongoose.model( 'Group', modelSchema );
    
     // account.js
    return Mongoose.model( 'Account', modelSchema );
    
    // app.js
    const models = require('./models/account.js')( Mongoose );
    
    models.findByUsername('jdoe', ( err, result ) => {