9

Consider a very simple Express 4 app structure:

-- app.js
-- models
     |--db.js
     |--news.js

where news.js contains a mongoose schema and a model based on that schema:

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

var newsSchema = new Schema({
    title: String,
    subtitle: String,
    // other fields...
});

var News = mongoose.model('News', newsSchema);

To my understanding, in order for app.js to use the News model, it has to require the file within the script like this: require('./models/news'). Also, news.js would have to export the model like this: module.exports = News;.

However, I have come across a number of scripts that do not export models (or anything for that matter) defined in a separate file while still be able to use those models and/or schema in a different file just by requiring the model file and then do something like this:

var mongoose = require('mongoose');
var News = mongoose.model('News');

How is this behavior possible? It is a special feature of Mongoose? How can a file use a model or schema defined in another file if that model/schema is not exported within that file?

Aren Li
  • 1,852
  • 1
  • 15
  • 14

1 Answers1

7

This ultimately works because when you call require('mongoose') in various files, you get back the same object. In other words: it gets shared between app.js and news.js, in your case.

When you create a new model (using mongoose.Model('Name', schema)), Mongoose stores that model instance in an internal list of models.

This also allows you to get an instance by name, using mongoose.Model('Name'). Mongoose will look up that model in its internal list, and return it.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • 3
    Hi Robert! Thank you for your reply! So the `mongoose` instance returned by calling `require('mongoose')` is a singleton? Therefore as soon as a model is registered, it becomes a part of the `mongoose` singleton. As long as the connection remains the same, calling `mongoose` from any script of the app would grant me access to the defined models. Is that right? – Aren Li Jul 08 '16 at 23:54
  • It makes sense to me now. However does the same behavior extend to Schema as well? If I define a schema in one script and do not export it, will other scripts that call `require('mongoose')` have access to the schema? Or is that behavior limited to models only, but not schema? – Aren Li Jul 08 '16 at 23:58
  • 2
    @ArenLi yes, it's basically a singleton. The same doesn't apply to schema, only models. I think that's because schema are regarded as being "private": they aren't of use besides creating models with (for instance, once you created a model from a schema, you can't change the schema for the model). – robertklep Jul 09 '16 at 07:40