Skip to content

Commit c4fac84

Browse files
authored
Merge pull request Automattic#15099 from Automattic/vkarpov15/Automatticgh-15088
fix(discriminator): gather childSchemas when creating discriminator to ensure $getAllSubdocs() can properly get all subdocs
2 parents 4cafc80 + 398b83c commit c4fac84

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

lib/helpers/model/discriminator.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ module.exports = function discriminator(model, name, schema, tiedValue, applyPlu
119119
// schema. `Schema.prototype.clone()` copies `obj` by reference, no cloning.
120120
schema.obj = { ...schema.obj };
121121
mergeDiscriminatorSchema(schema, baseSchema);
122+
schema._gatherChildSchemas();
122123

123124
// Clean up conflicting paths _after_ merging re: gh-6076
124125
for (const conflictingPath of conflictingPaths) {

lib/schema.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ Schema.prototype._clone = function _clone(Constructor) {
441441
}
442442
}
443443
}
444-
s.childSchemas = gatherChildSchemas(s);
444+
s._gatherChildSchemas();
445445

446446
s.virtuals = clone(this.virtuals);
447447
s.$globalPluginsApplied = this.$globalPluginsApplied;
@@ -1238,20 +1238,21 @@ Schema.prototype.path = function(path, obj) {
12381238
* ignore
12391239
*/
12401240

1241-
function gatherChildSchemas(schema) {
1241+
Schema.prototype._gatherChildSchemas = function _gatherChildSchemas() {
12421242
const childSchemas = [];
12431243

1244-
for (const path of Object.keys(schema.paths)) {
1245-
const schematype = schema.paths[path];
1244+
for (const path of Object.keys(this.paths)) {
1245+
const schematype = this.paths[path];
12461246
if (schematype.$isMongooseDocumentArray || schematype.$isSingleNested) {
12471247
childSchemas.push({ schema: schematype.schema, model: schematype.caster, path: path });
12481248
} else if (schematype.$isSchemaMap && schematype.$__schemaType.$isSingleNested) {
12491249
childSchemas.push({ schema: schematype.$__schemaType.schema, model: schematype.$__schemaType.caster, path: path });
12501250
}
12511251
}
12521252

1253+
this.childSchemas = childSchemas;
12531254
return childSchemas;
1254-
}
1255+
};
12551256

12561257
/*!
12571258
* ignore

test/model.discriminator.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,4 +2251,70 @@ describe('model', function() {
22512251
assert(result);
22522252

22532253
});
2254+
2255+
it('correctly gathers subdocs with discriminators (gh-15088)', async function() {
2256+
const RequestTriggeredWorkflowSchema = new Schema(
2257+
{
2258+
workflow: {
2259+
type: String
2260+
}
2261+
},
2262+
{
2263+
timestamps: true
2264+
}
2265+
);
2266+
2267+
const RequestSchema = new Schema(
2268+
{
2269+
status: {
2270+
type: String
2271+
},
2272+
summary: {
2273+
type: String
2274+
},
2275+
triggeredWorkflows: [RequestTriggeredWorkflowSchema]
2276+
},
2277+
{
2278+
discriminatorKey: 'source',
2279+
timestamps: true
2280+
}
2281+
);
2282+
2283+
const EmailRequestSchema = new Schema({
2284+
// Any extra properties that specifically apply to 'email' requests
2285+
});
2286+
const FormRequestSchema = new Schema({
2287+
// Any extra properties that specifically apply to 'form' requests
2288+
});
2289+
2290+
const Request = db.model('Request', RequestSchema);
2291+
2292+
Request.discriminator('Request:email', EmailRequestSchema, 'email');
2293+
Request.discriminator('Request:form', FormRequestSchema, 'form');
2294+
2295+
const request = await Request.create({
2296+
status: 'new',
2297+
source: 'form'
2298+
});
2299+
2300+
let requestAsReadFromDb = await Request.findById(request._id);
2301+
2302+
request.status = 'in progress';
2303+
await request.save();
2304+
2305+
assert.equal(requestAsReadFromDb.$getAllSubdocs().length, 0);
2306+
const now = new Date();
2307+
request.triggeredWorkflows.push({
2308+
workflow: '111111111111111111111111'
2309+
});
2310+
assert.equal(request.$getAllSubdocs().length, 1);
2311+
assert.equal(request.$getAllSubdocs()[0], request.triggeredWorkflows[0]);
2312+
await request.save();
2313+
2314+
requestAsReadFromDb = await Request.findById(request._id);
2315+
assert.equal(requestAsReadFromDb.$getAllSubdocs().length, 1);
2316+
assert.equal(requestAsReadFromDb.$getAllSubdocs()[0], requestAsReadFromDb.triggeredWorkflows[0]);
2317+
assert.ok(requestAsReadFromDb.triggeredWorkflows[0].createdAt.valueOf() >= now.valueOf());
2318+
assert.ok(requestAsReadFromDb.triggeredWorkflows[0].updatedAt.valueOf() >= now.valueOf());
2319+
});
22542320
});

0 commit comments

Comments
 (0)