diff --git a/lib/model.js b/lib/model.js index 0ced344223a..93e34c2eb33 100644 --- a/lib/model.js +++ b/lib/model.js @@ -4861,6 +4861,35 @@ Model.__subclass = function subclass(conn, schema, collection) { return Model; }; +/** + * Apply changes made to this model's schema after this model was compiled. + * By default, adding virtuals and other properties to a schema after the model is compiled does nothing. + * Call this function to apply virtuals and properties that were added later. + * + * #### Example: + * + * const schema = new mongoose.Schema({ field: String }); + * const TestModel = mongoose.model('Test', schema); + * TestModel.schema.virtual('myVirtual').get(function() { + * return this.field + ' from myVirtual'; + * }); + * const doc = new TestModel({ field: 'Hello' }); + * doc.myVirtual; // undefined + * + * TestModel.recompileSchema(); + * doc.myVirtual; // 'Hello from myVirtual' + * + * @return {undefined} + * @api public + * @memberOf Model + * @static + * @method recompileSchema + */ + +Model.recompileSchema = function recompileSchema() { + this.prototype.$__setSchema(this.schema); +}; + /** * Helper for console.log. Given a model named 'MyModel', returns the string * `'Model { MyModel }'`. diff --git a/test/model.test.js b/test/model.test.js index edff29ae047..3bd48f7018d 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -7302,6 +7302,19 @@ describe('Model', function() { /First argument to `Model` constructor must be an object/ ); }); + + it('supports recompiling model with new schema additions (gh-14296)', function() { + const schema = new mongoose.Schema({ field: String }); + const TestModel = db.model('Test', schema); + TestModel.schema.virtual('myVirtual').get(function() { + return this.field + ' from myVirtual'; + }); + const doc = new TestModel({ field: 'Hello' }); + assert.strictEqual(doc.myVirtual, undefined); + + TestModel.recompileSchema(); + assert.equal(doc.myVirtual, 'Hello from myVirtual'); + }); }); diff --git a/types/models.d.ts b/types/models.d.ts index caa4ea62696..1d879a7d48a 100644 --- a/types/models.d.ts +++ b/types/models.d.ts @@ -711,6 +711,9 @@ declare module 'mongoose' { options?: (mongodb.ReplaceOptions & MongooseQueryOptions) | null ): QueryWithHelpers; + /** Apply changes made to this model's schema after this model was compiled. */ + recompileSchema(): void; + /** Schema the model uses. */ schema: Schema;