Search code examples
mongoosemongoose-schemamongoose-populate

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


I have two models. On the first model I have a virtual field which should be populated by the other (one to many relationship). And it's not working.

Model one:

import { Schema, model } from 'mongoose';

const vendorSchema = new Schema<VendorProps>({
  company_name: String,
  product_type: String,
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
});

vendorSchema.virtual('campaigns', {
  ref: 'campaign',
  foreignField: 'vendor_id',
  localField: '_id'
});

const Vendor = model<VendorProps>(
  'Vendor',
  vendorSchema
);

export default Vendor;

Model two:

import { Schema, model } from 'mongoose';

const campaignSchema = new Schema<CampaignProps>({
  lead_volume: Number,
  cost_per_credit_score: String,
  vendor_id: {
    type: Schema.ObjectId,
    ref: 'Vendor',
  },
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
});

const Campaign = model<CampaignProps>(
  'campaign',
  campaignSchema
);

export default Campaign;

(i have omited the Props as they're .ts files)

In the index file i import the route which references the controller method bellow:

import VendorModel from '../models/vendor';
await VendorModel.findById(id).populate('campaigns').exec();

I have at least 12 other similar models which works the exact same way. (when i was creating these two + controller, i just literally copy/pasted and modified the names) But for some reason when i query for the Vendor type by ID it gives me the title error.

I am completely stumped. ( i looked over a few other similar threads here on SO but none of them could help me as I think there is literally nothing wrong my code, it should work)

Any ideas?


Solution

  • So i accidentally figured out why this wasn't working. The Campaign model wasn't being used anywhere (apart in the populate query).

    After I created I added the model to an existing route (as a query) the code worked. So basically the model wasn't "registered" and so model one was referencing a non-existing model (if you asked mongoose, and we are).

    tl:dr; you have to have a reference in your code to the model in order for the virtual field to work.