-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration for ES6 classes #4668
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -309,14 +309,23 @@ Mongoose.prototype.disconnect.$hasSideEffects = true; | |
* var collectionName = 'actor' | ||
* var M = mongoose.model('Actor', schema, collectionName) | ||
* | ||
* @param {String} name model name | ||
* @param {String|Function} name model name or class extending Model | ||
* @param {Schema} [schema] | ||
* @param {String} [collection] name (optional, induced from model name) | ||
* @param {String} [collection] name (optional, inferred from model name) | ||
* @param {Boolean} [skipInit] whether to skip initialization (defaults to false) | ||
* @api public | ||
*/ | ||
|
||
Mongoose.prototype.model = function(name, schema, collection, skipInit) { | ||
var model; | ||
if (typeof name === 'function') { | ||
model = name; | ||
name = model.name; | ||
if (!(model.prototype instanceof Model)) { | ||
throw new mongoose.Error('The provided class ' + name + ' must extend Model'); | ||
} | ||
} | ||
|
||
if (typeof schema === 'string') { | ||
collection = schema; | ||
schema = false; | ||
|
@@ -354,7 +363,6 @@ Mongoose.prototype.model = function(name, schema, collection, skipInit) { | |
this._applyPlugins(schema); | ||
} | ||
|
||
var model; | ||
var sub; | ||
|
||
// connection.model() may be passing a different schema for | ||
|
@@ -393,7 +401,7 @@ Mongoose.prototype.model = function(name, schema, collection, skipInit) { | |
} | ||
|
||
var connection = options.connection || this.connection; | ||
model = this.Model.compile(name, schema, collection, connection, this); | ||
model = this.Model.compile(model || name, schema, collection, connection, this); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this change needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure where the problem you see is, can you elaborate? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. I just saw the diff and thought it wasn't necessary based on my misunderstanding of what the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I first looked at this, I thought this bit was still inside the |
||
|
||
if (!skipInit) { | ||
model.init(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3190,7 +3190,7 @@ Model._getSchema = function _getSchema(path) { | |
/*! | ||
* Compiler utility. | ||
* | ||
* @param {String} name model name | ||
* @param {String|Function} name model name or class extending Model | ||
* @param {Schema} schema | ||
* @param {String} collectionName | ||
* @param {Connection} connection | ||
|
@@ -3207,19 +3207,28 @@ Model.compile = function compile(name, schema, collectionName, connection, base) | |
schema.add(o); | ||
} | ||
|
||
// generate new class | ||
function model(doc, fields, skipId) { | ||
if (!(this instanceof model)) { | ||
return new model(doc, fields, skipId); | ||
} | ||
Model.call(this, doc, fields, skipId); | ||
var model; | ||
if (typeof name === 'function' && name.prototype instanceof Model) { | ||
model = name; | ||
name = model.name; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is the '.name' defined? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because With a class this is the name of the class. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we want our model to have a name different than the class name, i.e if our model is name is 'my.function'? We have to override it? i.e
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. name is a read-only property, so you can't change it I suggest you look at the link that vkarpov15 commented to use .LoadClass into the schema you want |
||
schema.loadClass(model, true); | ||
} else { | ||
// generate new class | ||
model = function model(doc, fields, skipId) { | ||
if (!(this instanceof model)) { | ||
return new model(doc, fields, skipId); | ||
} | ||
Model.call(this, doc, fields, skipId); | ||
}; | ||
} | ||
|
||
model.hooks = schema.s.hooks.clone(); | ||
model.base = base; | ||
model.modelName = name; | ||
model.__proto__ = Model; | ||
model.prototype.__proto__ = Model.prototype; | ||
if (!(model.prototype instanceof Model)) { | ||
model.__proto__ = Model; | ||
model.prototype.__proto__ = Model.prototype; | ||
} | ||
model.model = Model.prototype.model; | ||
model.db = model.prototype.db = connection; | ||
model.discriminators = model.prototype.discriminators = undefined; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1509,28 +1509,32 @@ Schema.prototype.remove = function(path) { | |
* | ||
* @param {Function} model | ||
*/ | ||
Schema.prototype.loadClass = function(model) { | ||
Schema.prototype.loadClass = function(model, virtualsOnly) { | ||
if (model === Object.prototype || model === Function.prototype) { | ||
return this; | ||
} | ||
|
||
// Add static methods | ||
Object.getOwnPropertyNames(model).forEach(function(name) { | ||
if (name.match(/^(length|name|prototype)$/)) { | ||
return; | ||
} | ||
var method = Object.getOwnPropertyDescriptor(model, name); | ||
if (typeof method.value === 'function') this.static(name, method.value); | ||
}, this); | ||
if (!virtualsOnly) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm what's the point of this virtualsOnly option? Looks like it's always true anyway... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose it's probably unnecessary. Its only use is mainly internal by It seems like Schemas need the virtuals defined on them directly for them to function properly, e.g. in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify,
In this case virtualsOnly is |
||
Object.getOwnPropertyNames(model).forEach(function(name) { | ||
if (name.match(/^(length|name|prototype)$/)) { | ||
return; | ||
} | ||
var method = Object.getOwnPropertyDescriptor(model, name); | ||
if (typeof method.value === 'function') this.static(name, method.value); | ||
}, this); | ||
} | ||
|
||
// Add methods and virtuals | ||
Object.getOwnPropertyNames(model.prototype).forEach(function(name) { | ||
if (name.match(/^(constructor)$/)) { | ||
return; | ||
} | ||
var method = Object.getOwnPropertyDescriptor(model.prototype, name); | ||
if (typeof method.value === 'function') { | ||
this.method(name, method.value); | ||
if (!virtualsOnly) { | ||
if (typeof method.value === 'function') { | ||
this.method(name, method.value); | ||
} | ||
} | ||
if (typeof method.get === 'function') { | ||
this.virtual(name).get(method.get); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong.. I don't think this would work in the case when using a Base class on an individual class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No,
instanceof
looks through the whole prototype chain. So as long asMyBase
extendsModel
, it's fine. I'm actually currently using this use ofextends
for some of the models in my app.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for clarifying that. I didn't know that about
instanceof
; obviously :)