0

Currently using Mongoose with MongoDB for an Express server, however I attempted to link up several Mongoose models together and I am getting

MissingSchemaError: Schema hasn't been registered for model "Semester".
Use mongoose.model(name, schema)

with my execution.

The current project structure is as follows

app.js
www.js
models
|-- member.js
|-- semester.js
routes
|-- members.js

I've reviewed about two dozen other Stackoverflow questions regarding the same error and all of which pointed at using require for the model(s) before require('express').

However, I am currently following that practice but still getting an unrecognized Schema (which leads me to believe that how I linked the models together was incorrect).

app.js

// DEPENDENCIES
var bodyParser = require('body-parser');
var mongoose = require('mongoose'); // NOTE: Mongoose needs to be required before express

// MODELS   
require('./models/member');
require('./models/semester');

// ROUTES
var members = require('./routes/members'); // NOTE: Routes need to be required before express as well

var express = require('express');
var app = express();

// ... More Stuff ...

module.exports = app;

My ./routes/members.js

var Member = require('../app/models/member');
require('../app/models/semester');
var express = require('express');

var router = express.Router();

// ... Logic is here ...

module.exports = router;

Finally the models themselves member.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Semester = require('mongoose').model('Semester').schema;
// Would var Semester = mongoose.model('Semester').schema also work?

var MemberSchema = new Schema({
  name: {
    first: {type: String, default: ''},
    last: {type: String, default: ''}
  },
  studentID: {type: Number, default: 0},
  email: {type: String, default: ''},
  social: {type: Social},
  semesters: [Semester],
  currenPosition: {type: String, default: ''}
});
module.exports = mongoose.model('Member', MemberSchema);

semester.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Event = require('mongoose').model('Event').schema; // These are valid models, but I haven't included them in the scope of this question
var Project = require('mongoose').model('Project').schema;

// Object which describes a singular semester
var SemesterSchema  = new Schema({
  term: {type: String, default: ''},
  year: {type: Number, default: ''},
  position: {type: String, default: ''}
  events: [Event],
  projects: [Project]
});

module.exports = mongoose.model('Semester', SemesterSchema);

I am rather certain at this point that it's a non-mongoose related mistake I made when requiring and linking different models together.

Jacob Young
  • 25
  • 1
  • 8

1 Answers1

0

This error could be happening because you're requiring Member model before Semester in app.js, this is because Semester model and schema not exist when './models/member' is required

Try to change the order in app.js to:

// MODELS   
require('./models/semester');
require('./models/member');

To avoid this situation you could require the model from the script file ('./models/semester') instead of obtaining it from mongoose through model in the script file were Member model is declared (./models/member)

Leon Plata
  • 627
  • 5
  • 9
  • Great, that actually solved it, thank you! Just one more question: Is it bad practice to cross reference models? Example: I have the `Member` model. I also have an `Event` model. But inside `Event` I construct a Schema field which takes an array of `Members`. It would seem that this would be impossible to solve because both require each other simultaneously and I can only order the `require` statements linearly in `app.js` – Jacob Young Jun 21 '15 at 09:13
  • Actually when a mongoose schema is declared inside another mongoose schema is not a reference, is an inner document that accomplish with the validation schema only, so for create references to another collections the id's type and the collection reference should be declared in the schema ( [mongoose documentation](http://mongoosejs.com/docs/populate.html) ) – Leon Plata Jun 21 '15 at 19:20
  • You can use id referencing to handle cross references but you need to make validations for deletions and updates to have consistence in your db, about using inner or embedded documents or references this answer let me satisfied http://stackoverflow.com/questions/5373198/mongodb-relationships-embed-or-reference – Leon Plata Jun 21 '15 at 19:39