Skip to content

Commit 18d5d79

Browse files
authored
Merge pull request #13938 from Automattic/IslandRhythms/gh-13906
Island rhythms/gh 13906 handle changing discrim key
2 parents d5964cd + 29aa4fc commit 18d5d79

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

lib/cast.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ module.exports = function cast(schema, obj, options, context) {
6868
if (val[k] == null || typeof val[k] !== 'object') {
6969
throw new CastError('Object', val[k], path + '.' + k);
7070
}
71-
val[k] = cast(schema, val[k], options, context);
71+
const discriminatorValue = val[k][schema.options.discriminatorKey];
72+
if (discriminatorValue == null) {
73+
val[k] = cast(schema, val[k], options, context);
74+
} else {
75+
const discriminatorSchema = getSchemaDiscriminatorByValue(context.schema, discriminatorValue);
76+
val[k] = cast(discriminatorSchema ? discriminatorSchema : schema, val[k], options, context);
77+
}
7278
}
7379
} else if (path === '$where') {
7480
type = typeof val;
@@ -303,7 +309,6 @@ module.exports = function cast(schema, obj, options, context) {
303309
} else {
304310
const ks = Object.keys(val);
305311
let $cond;
306-
307312
let k = ks.length;
308313

309314
while (k--) {

lib/query.js

-1
Original file line numberDiff line numberDiff line change
@@ -4889,7 +4889,6 @@ function _getPopulatedPaths(list, arr, prefix) {
48894889

48904890
Query.prototype.cast = function(model, obj) {
48914891
obj || (obj = this._conditions);
4892-
48934892
model = model || this.model;
48944893
const discriminatorKey = model.schema.options.discriminatorKey;
48954894
if (obj != null &&

lib/schematype.js

-1
Original file line numberDiff line numberDiff line change
@@ -1215,7 +1215,6 @@ SchemaType.prototype.applySetters = function(value, scope, init, priorVal, optio
12151215
if (v == null) {
12161216
return this._castNullish(v);
12171217
}
1218-
12191218
// do not cast until all setters are applied #665
12201219
v = this.cast(v, scope, init, priorVal, options);
12211220

test/model.discriminator.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -2180,4 +2180,34 @@ describe('model', function() {
21802180
assert.ok(innerBuildingsPath.schemaOptions.type.discriminators.Garage);
21812181
assert.equal(innerBuildingsPath.schemaOptions.type.discriminators.Garage.discriminatorMapping.value, 'G');
21822182
});
2183+
it('should not fail when using a discriminator key multiple times (gh-13906)', async function() {
2184+
const options = { discriminatorKey: 'type' };
2185+
const eventSchema = new Schema({ date: Schema.Types.Date }, options);
2186+
const Event = db.model('gh-13906-event', eventSchema);
2187+
2188+
2189+
const clickedLinkEventSchema = new Schema({ url: String }, options);
2190+
const ClickedLinkEvent = Event.discriminator('ClickedLinkEvent', clickedLinkEventSchema, 'clickedLinkEvent');
2191+
2192+
2193+
const clickedImageEventSchema = new Schema({ image: String }, options);
2194+
const ClickedImageEvent = Event.discriminator('ClickedImageEvent', clickedImageEventSchema, 'clickedImageEvent');
2195+
2196+
const clickedLinkEvent = new ClickedLinkEvent({ url: 'https://clicked-link.com' });
2197+
assert.equal(clickedLinkEvent.type, 'clickedLinkEvent');
2198+
assert.equal(clickedLinkEvent.url, 'https://clicked-link.com');
2199+
2200+
const clickedImageEvent = new ClickedImageEvent({ image: 'clicked-image.png' });
2201+
assert.equal(clickedImageEvent.type, 'clickedImageEvent');
2202+
assert.equal(clickedImageEvent.image, 'clicked-image.png');
2203+
const query = {
2204+
type: 'clickedLinkEvent',
2205+
$or: [
2206+
{ type: 'clickedImageEvent' }
2207+
]
2208+
};
2209+
const result = await Event.find(query).exec();
2210+
assert(result);
2211+
2212+
});
21832213
});

0 commit comments

Comments
 (0)