Skip to content

Commit

Permalink
feat(model): inherit options from discriminator base schema
Browse files Browse the repository at this point in the history
Fix #3414
  • Loading branch information
vkarpov15 committed Apr 9, 2016
1 parent 9c6a73d commit 3ce74fb
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 29 deletions.
45 changes: 24 additions & 21 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,14 @@ Model.prototype.model = function model(name) {
* @api public
*/

var CUSTOMIZABLE_DISCRIMINATOR_OPTIONS = {
toJSON: true,
toObject: true,
_id: true,
id: true,
processError: true
};

Model.discriminator = function discriminator(name, schema) {
if (!(schema && schema.instanceOfSchema)) {
throw new Error('You must pass a valid discriminator Schema');
Expand All @@ -789,24 +797,6 @@ Model.discriminator = function discriminator(name, schema) {
'" cannot have field with name "' + key + '"');
}

function clean(a, b) {
a = utils.clone(a);
b = utils.clone(b);
delete a.toJSON;
delete a.toObject;
delete b.toJSON;
delete b.toObject;
delete a._id;
delete b._id;
delete a.processError;
delete b.processError;

if (!utils.deepEqual(a, b)) {
throw new Error('Discriminator options are not customizable ' +
'(except toJSON, toObject, _id)');
}
}

function merge(schema, baseSchema) {
utils.merge(schema, baseSchema);

Expand All @@ -819,19 +809,32 @@ Model.discriminator = function discriminator(name, schema) {
schema.options.collection = baseSchema.options.collection;
}

// throws error if options are invalid
clean(schema.options, baseSchema.options);

var toJSON = schema.options.toJSON;
var toObject = schema.options.toObject;
var _id = schema.options._id;
var id = schema.options.id;

var keys = Object.keys(schema.options);

for (var i = 0; i < keys.length; ++i) {
var _key = keys[i];
if (!CUSTOMIZABLE_DISCRIMINATOR_OPTIONS[_key]) {
if (!utils.deepEqual(schema.options[_key], baseSchema.options[_key])) {
throw new Error('Can\'t customize discriminator option ' + _key +
' (can only modify ' +
Object.keys(CUSTOMIZABLE_DISCRIMINATOR_OPTIONS).join(', ') +
')');
}
}
}

schema.options = utils.clone(baseSchema.options);
if (toJSON) schema.options.toJSON = toJSON;
if (toObject) schema.options.toObject = toObject;
if (typeof _id !== 'undefined') {
schema.options._id = _id;
}
schema.options.id = id;

schema.callQueue = baseSchema.callQueue.concat(schema.callQueue.slice(schema._defaultMiddleware.length));
schema._requiredpaths = undefined; // reset just in case Schema#requiredPaths() was called on either schema
Expand Down
13 changes: 5 additions & 8 deletions test/model.discriminator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ describe('model', function() {
var PersonSchema = new BaseSchema();
var BossSchema = new BaseSchema({
department: String
});
}, { id: false });

assert.doesNotThrow(function() {
var Person = db.model('gh2821', PersonSchema);
Expand All @@ -249,15 +249,12 @@ describe('model', function() {
});

it('is not customizable', function(done) {
var errorMessage,
CustomizedSchema = new Schema({}, {capped: true});
try {
var CustomizedSchema = new Schema({}, {capped: true});

assert.throws(function() {
Person.discriminator('model-discriminator-custom', CustomizedSchema);
} catch (e) {
errorMessage = e.message;
}
}, /Can't customize discriminator option capped/);

assert.equal(errorMessage, 'Discriminator options are not customizable (except toJSON, toObject, _id)');
done();
});
});
Expand Down

0 comments on commit 3ce74fb

Please sign in to comment.