不要怂,就是干,撸起袖子干!

Commit d2545644 by Felix Becker Committed by Jan Aagaard Meier

Make instances instanceof Model, with ES6 classes (#5924)

* Make Instance an ES6 class

* Add esversion: 6 to jshintrc

* Make Model an ES6 class

* Merge Model class into Instance class

* Rename instance.js to model.js

* Remove name parameter from Model.init()

The name is set when subclassing the Model class

* Change sequelize.define() to a Model class factory

* Delete model.js

* Remove Model.Instance and Model.prototype.Model

* Fix JSHint issue

* Remove leftover require('./instance')

* Fix reference to old Instance class

* Remove references to old Instance class from main module

* Reorder imports to hopefully trigger Travis Build

* Fix _addOptionalClassMethods call

* Fix more references to .Instance

* Correct uses of .Model

* Fix use of this in closure

* Fix usage of instanceof Model

* Fix usage of .Model

* Fix usage of this in closure

* Fix usage of $Model

* Fix test for `plain` option

* Fix uses of .$Model

* Fix hooks

* Fix global hooks

* Make more tests pass

* Make more tests pass

* Fix Model.prototype references in findone test

* Change Model.schema()

* Fix instanceof checks in belongs-to-many association

* Fix Model.scope()

* Remove callback support from hooks

* Fix instanceof Model checks

* Fix usage of instanceof Model

* Change another occurence of .Model.name to .constructor.name

* Replace .constructor by .Model again

* Fix this inside closure

* Change test cosntructor assertions to instanceof checks
1 parent 738ea1b2
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
/* questionable */ /* questionable */
"loopfunc":true, "loopfunc":true,
"esversion": 6,
"globals": { "globals": {
"Promise": true "Promise": true
}, },
......
...@@ -8,7 +8,7 @@ Association.prototype.toInstanceArray = function (objs) { ...@@ -8,7 +8,7 @@ Association.prototype.toInstanceArray = function (objs) {
objs = [objs]; objs = [objs];
} }
return objs.map(function(obj) { return objs.map(function(obj) {
if (!(obj instanceof this.target.Instance)) { if (!(obj instanceof this.target)) {
var tmpInstance = {}; var tmpInstance = {};
tmpInstance[this.target.primaryKeyAttribute] = obj; tmpInstance[this.target.primaryKeyAttribute] = obj;
return this.target.build(tmpInstance, { return this.target.build(tmpInstance, {
......
...@@ -521,7 +521,7 @@ BelongsToMany.prototype.injectGetter = function(obj) { ...@@ -521,7 +521,7 @@ BelongsToMany.prototype.injectGetter = function(obj) {
}); });
where.$or = instances.map(function (instance) { where.$or = instances.map(function (instance) {
if (instance instanceof association.target.Instance) { if (instance instanceof association.target) {
return instance.where(); return instance.where();
} else { } else {
var $where = {}; var $where = {};
...@@ -592,7 +592,7 @@ BelongsToMany.prototype.injectSetter = function(obj) { ...@@ -592,7 +592,7 @@ BelongsToMany.prototype.injectSetter = function(obj) {
} else { } else {
var throughAttributes = newObj[association.through.model.name]; var throughAttributes = newObj[association.through.model.name];
// Quick-fix for subtle bug when using existing objects that might have the through model attached (not as an attribute object) // Quick-fix for subtle bug when using existing objects that might have the through model attached (not as an attribute object)
if (throughAttributes instanceof association.through.model.Instance) { if (throughAttributes instanceof association.through.model) {
throughAttributes = {}; throughAttributes = {};
} }
...@@ -712,7 +712,7 @@ BelongsToMany.prototype.injectSetter = function(obj) { ...@@ -712,7 +712,7 @@ BelongsToMany.prototype.injectSetter = function(obj) {
, attributes = _.defaults({}, throughAttributes, defaultAttributes) , attributes = _.defaults({}, throughAttributes, defaultAttributes)
, where = {}; , where = {};
// Quick-fix for subtle bug when using existing objects that might have the through model attached (not as an attribute object) // Quick-fix for subtle bug when using existing objects that might have the through model attached (not as an attribute object)
if (throughAttributes instanceof association.through.model.Instance) { if (throughAttributes instanceof association.through.model) {
throughAttributes = {}; throughAttributes = {};
} }
......
...@@ -213,7 +213,7 @@ BelongsTo.prototype.injectSetter = function(instancePrototype) { ...@@ -213,7 +213,7 @@ BelongsTo.prototype.injectSetter = function(instancePrototype) {
options = options || {}; options = options || {};
var value = associatedInstance; var value = associatedInstance;
if (associatedInstance instanceof association.target.Instance) { if (associatedInstance instanceof association.target) {
value = associatedInstance[association.targetKey]; value = associatedInstance[association.targetKey];
} }
......
...@@ -366,7 +366,7 @@ HasMany.prototype.has = function(sourceInstance, targetInstances, options) { ...@@ -366,7 +366,7 @@ HasMany.prototype.has = function(sourceInstance, targetInstances, options) {
}); });
where.$or = targetInstances.map(function (instance) { where.$or = targetInstances.map(function (instance) {
if (instance instanceof association.target.Instance) { if (instance instanceof association.target) {
return instance.where(); return instance.where();
} else { } else {
var _where = {}; var _where = {};
......
...@@ -228,7 +228,7 @@ HasOne.prototype.injectSetter = function(instancePrototype) { ...@@ -228,7 +228,7 @@ HasOne.prototype.injectSetter = function(instancePrototype) {
} }
}).then(function() { }).then(function() {
if (associatedInstance && !alreadyAssociated) { if (associatedInstance && !alreadyAssociated) {
if (!(associatedInstance instanceof association.target.Instance)) { if (!(associatedInstance instanceof association.target)) {
var tmpInstance = {}; var tmpInstance = {};
tmpInstance[association.target.primaryKeyAttribute] = associatedInstance; tmpInstance[association.target.primaryKeyAttribute] = associatedInstance;
associatedInstance = association.target.build(tmpInstance, { associatedInstance = association.target.build(tmpInstance, {
......
...@@ -91,8 +91,8 @@ var Mixin = module.exports = function() {}; ...@@ -91,8 +91,8 @@ var Mixin = module.exports = function() {};
// The logic for hasOne and belongsTo is exactly the same // The logic for hasOne and belongsTo is exactly the same
var singleLinked = function (Type) { var singleLinked = function (Type) {
return function(target, options) { // testhint options:none return function(target, options) { // testhint options:none
if (!(target instanceof this.sequelize.Model)) { if (!target.prototype || !(target.prototype instanceof this.sequelize.Model)) {
throw new Error(this.name + '.' + Utils.lowercaseFirst(Type.toString()) + ' called with something that\'s not an instance of Sequelize.Model'); throw new Error(this.name + '.' + Utils.lowercaseFirst(Type.toString()) + ' called with something that\'s not a subclass of Sequelize.Model');
} }
var source = this; var source = this;
...@@ -107,11 +107,11 @@ var singleLinked = function (Type) { ...@@ -107,11 +107,11 @@ var singleLinked = function (Type) {
source.associations[association.associationAccessor] = association.injectAttributes(); source.associations[association.associationAccessor] = association.injectAttributes();
if (association.mixin) { if (association.mixin) {
association.mixin(source.Instance.prototype); association.mixin(source.prototype);
} else { } else {
association.injectGetter(source.Instance.prototype); association.injectGetter(source.prototype);
association.injectSetter(source.Instance.prototype); association.injectSetter(source.prototype);
association.injectCreator(source.Instance.prototype); association.injectCreator(source.prototype);
} }
return association; return association;
...@@ -168,8 +168,8 @@ Mixin.belongsTo = singleLinked(BelongsTo); ...@@ -168,8 +168,8 @@ Mixin.belongsTo = singleLinked(BelongsTo);
* @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key. * @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key.
*/ */
Mixin.hasMany = function(target, options) { // testhint options:none Mixin.hasMany = function(target, options) { // testhint options:none
if (!(target instanceof this.sequelize.Model)) { if (!target.prototype || !(target.prototype instanceof this.sequelize.Model)) {
throw new Error(this.name + '.hasMany called with something that\'s not an instance of Sequelize.Model'); throw new Error(this.name + '.hasMany called with something that\'s not a subclass of Sequelize.Model');
} }
var source = this; var source = this;
...@@ -186,7 +186,7 @@ Mixin.hasMany = function(target, options) { // testhint options:none ...@@ -186,7 +186,7 @@ Mixin.hasMany = function(target, options) { // testhint options:none
source.associations[association.associationAccessor] = association; source.associations[association.associationAccessor] = association;
association.injectAttributes(); association.injectAttributes();
association.mixin(source.Instance.prototype); association.mixin(source.prototype);
return association; return association;
}; };
...@@ -247,8 +247,8 @@ Mixin.hasMany = function(target, options) { // testhint options:none ...@@ -247,8 +247,8 @@ Mixin.hasMany = function(target, options) { // testhint options:none
* @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key. * @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key.
*/ */
Mixin.belongsToMany = function(targetModel, options) { // testhint options:none Mixin.belongsToMany = function(targetModel, options) { // testhint options:none
if (!(targetModel instanceof this.sequelize.Model)) { if (!targetModel.prototype || !(targetModel.prototype instanceof this.sequelize.Model)) {
throw new Error(this.name + '.belongsToMany called with something that\'s not an instance of Sequelize.Model'); throw new Error(this.name + '.belongsToMany called with something that\'s not a subclass of Sequelize.Model');
} }
var sourceModel = this; var sourceModel = this;
...@@ -264,9 +264,9 @@ Mixin.belongsToMany = function(targetModel, options) { // testhint options:none ...@@ -264,9 +264,9 @@ Mixin.belongsToMany = function(targetModel, options) { // testhint options:none
var association = new BelongsToMany(sourceModel, targetModel, options); var association = new BelongsToMany(sourceModel, targetModel, options);
sourceModel.associations[association.associationAccessor] = association.injectAttributes(); sourceModel.associations[association.associationAccessor] = association.injectAttributes();
association.injectGetter(sourceModel.Instance.prototype); association.injectGetter(sourceModel.prototype);
association.injectSetter(sourceModel.Instance.prototype); association.injectSetter(sourceModel.prototype);
association.injectCreator(sourceModel.Instance.prototype); association.injectCreator(sourceModel.prototype);
return association; return association;
}; };
......
...@@ -662,7 +662,7 @@ var QueryGenerator = { ...@@ -662,7 +662,7 @@ var QueryGenerator = {
options = this.nameIndexes([options], options.prefix)[0]; options = this.nameIndexes([options], options.prefix)[0];
} }
options = Model.prototype.$conformIndex(options); options = Model.$conformIndex(options);
if (!this._dialect.supports.index.type) { if (!this._dialect.supports.index.type) {
delete options.type; delete options.type;
...@@ -823,7 +823,7 @@ var QueryGenerator = { ...@@ -823,7 +823,7 @@ var QueryGenerator = {
break; break;
} }
if (item instanceof Model) { if (typeof item === 'function' && item.prototype instanceof Model) {
model = item; model = item;
as = undefined; as = undefined;
} else { } else {
...@@ -1528,7 +1528,7 @@ var QueryGenerator = { ...@@ -1528,7 +1528,7 @@ var QueryGenerator = {
} else { } else {
query += ' FOR UPDATE'; query += ' FOR UPDATE';
} }
if (this._dialect.supports.lockOf && options.lock.of instanceof Model) { if (this._dialect.supports.lockOf && options.lock.of && options.lock.of.prototype instanceof Model) {
query += ' OF ' + this.quoteTable(options.lock.of.name); query += ' OF ' + this.quoteTable(options.lock.of.name);
} }
} }
...@@ -1562,7 +1562,7 @@ var QueryGenerator = { ...@@ -1562,7 +1562,7 @@ var QueryGenerator = {
if (Array.isArray(options.order)) { if (Array.isArray(options.order)) {
options.order.forEach(function(t) { options.order.forEach(function(t) {
if (Array.isArray(t) && _.size(t) > 1) { if (Array.isArray(t) && _.size(t) > 1) {
if (t[0] instanceof Model || t[0].model instanceof Model) { if ((typeof t[0] === 'function' && t[0].prototype instanceof Model) || (typeof t[0].model === 'function' && t[0].model.prototype instanceof Model)) {
if (typeof t[t.length - 2] === 'string') { if (typeof t[t.length - 2] === 'string') {
validateOrder(_.last(t)); validateOrder(_.last(t));
} }
...@@ -1571,7 +1571,7 @@ var QueryGenerator = { ...@@ -1571,7 +1571,7 @@ var QueryGenerator = {
} }
} }
if (subQuery && (Array.isArray(t) && !(t[0] instanceof Model) && !(t[0].model instanceof Model))) { if (subQuery && (Array.isArray(t) && !(typeof t[0] === 'function' && t[0].prototype instanceof Model) && !(t[0] && typeof t[0].model === 'function' && t[0].model.prototype instanceof Model))) {
subQueryOrder.push(this.quote(t, model)); subQueryOrder.push(this.quote(t, model));
} }
......
...@@ -100,14 +100,9 @@ var Hooks = { ...@@ -100,14 +100,9 @@ var Hooks = {
runHooks: function(hooks) { runHooks: function(hooks) {
var self = this var self = this
, fn
, fnArgs = Utils.sliceArgs(arguments, 1) , fnArgs = Utils.sliceArgs(arguments, 1)
, hookType; , hookType;
if (typeof fnArgs[fnArgs.length - 1] === 'function') {
fn = fnArgs.pop();
}
if (typeof hooks === 'string') { if (typeof hooks === 'string') {
hookType = hooks; hookType = hooks;
hooks = this.options.hooks[hookType] || []; hooks = this.options.hooks[hookType] || [];
...@@ -141,10 +136,6 @@ var Hooks = { ...@@ -141,10 +136,6 @@ var Hooks = {
return hook.apply(self, fnArgs); return hook.apply(self, fnArgs);
}).return(); }).return();
if (fn) {
return promise.nodeify(fn);
}
return promise; return promise;
}, },
...@@ -467,7 +458,7 @@ module.exports = { ...@@ -467,7 +458,7 @@ module.exports = {
var allHooks = Object.keys(hookTypes).concat(Object.keys(hookAliases)); var allHooks = Object.keys(hookTypes).concat(Object.keys(hookAliases));
allHooks.forEach(function(hook) { allHooks.forEach(function(hook) {
Model.prototype[hook] = function(name, callback) { Model[hook] = Model.prototype[hook] = function(name, callback) {
return this.addHook(hook, name, callback); return this.addHook(hook, name, callback);
}; };
}); });
......
...@@ -19,7 +19,7 @@ var InstanceValidator = module.exports = function(modelInstance, options) { ...@@ -19,7 +19,7 @@ var InstanceValidator = module.exports = function(modelInstance, options) {
options = _.clone(options) || {}; options = _.clone(options) || {};
if (options.fields && !options.skip) { if (options.fields && !options.skip) {
options.skip = Utils._.difference(Object.keys(modelInstance.Model.attributes), options.fields); options.skip = Utils._.difference(Object.keys(modelInstance.constructor.attributes), options.fields);
} }
// assign defined and default options // assign defined and default options
...@@ -87,14 +87,14 @@ InstanceValidator.prototype._validate = function() { ...@@ -87,14 +87,14 @@ InstanceValidator.prototype._validate = function() {
*/ */
InstanceValidator.prototype.validate = function() { InstanceValidator.prototype.validate = function() {
if (this.options.hooks) { if (this.options.hooks) {
return this.modelInstance.Model.runHooks('beforeValidate', this.modelInstance, this.options).bind(this).then(function() { return this.modelInstance.constructor.runHooks('beforeValidate', this.modelInstance, this.options).bind(this).then(function() {
return this._validate().bind(this).catch(function(error) { return this._validate().bind(this).catch(function(error) {
return this.modelInstance.Model.runHooks('validationFailed', this.modelInstance, this.options, error).then(function(newError) { return this.modelInstance.constructor.runHooks('validationFailed', this.modelInstance, this.options, error).then(function(newError) {
throw newError || error; throw newError || error;
}); });
}); });
}).then(function() { }).then(function() {
return this.modelInstance.Model.runHooks('afterValidate', this.modelInstance, this.options); return this.modelInstance.constructor.runHooks('afterValidate', this.modelInstance, this.options);
}).return(this.modelInstance); }).return(this.modelInstance);
} }
return this._validate(); return this._validate();
......
...@@ -492,8 +492,8 @@ QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes ...@@ -492,8 +492,8 @@ QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes
QueryInterface.prototype.insert = function(instance, tableName, values, options) { QueryInterface.prototype.insert = function(instance, tableName, values, options) {
options = Utils.cloneDeep(options); options = Utils.cloneDeep(options);
options.hasTrigger = instance && instance.Model.options.hasTrigger; options.hasTrigger = instance && instance.constructor.options.hasTrigger;
var sql = this.QueryGenerator.insertQuery(tableName, values, instance && instance.Model.rawAttributes, options); var sql = this.QueryGenerator.insertQuery(tableName, values, instance && instance.constructor.rawAttributes, options);
options.type = QueryTypes.INSERT; options.type = QueryTypes.INSERT;
options.instance = instance; options.instance = instance;
...@@ -575,18 +575,18 @@ QueryInterface.prototype.update = function(instance, tableName, values, identifi ...@@ -575,18 +575,18 @@ QueryInterface.prototype.update = function(instance, tableName, values, identifi
var self = this var self = this
, restrict = false , restrict = false
, sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options, instance.Model.rawAttributes); , sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options, instance.constructor.rawAttributes);
options.type = QueryTypes.UPDATE; options.type = QueryTypes.UPDATE;
// Check for a restrict field // Check for a restrict field
if (!!instance.Model && !!instance.Model.associations) { if (instance.constructor && instance.constructor.associations) {
var keys = Object.keys(instance.Model.associations) var keys = Object.keys(instance.constructor.associations)
, length = keys.length; , length = keys.length;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
if (instance.Model.associations[keys[i]].options && instance.Model.associations[keys[i]].options.onUpdate && instance.Model.associations[keys[i]].options.onUpdate === 'restrict') { if (instance.constructor.associations[keys[i]].options && instance.constructor.associations[keys[i]].options.onUpdate && instance.constructor.associations[keys[i]].options.onUpdate === 'restrict') {
restrict = true; restrict = true;
} }
} }
...@@ -611,18 +611,18 @@ QueryInterface.prototype.bulkUpdate = function(tableName, values, identifier, op ...@@ -611,18 +611,18 @@ QueryInterface.prototype.bulkUpdate = function(tableName, values, identifier, op
QueryInterface.prototype.delete = function(instance, tableName, identifier, options) { QueryInterface.prototype.delete = function(instance, tableName, identifier, options) {
var self = this var self = this
, cascades = [] , cascades = []
, sql = self.QueryGenerator.deleteQuery(tableName, identifier, null, instance.Model); , sql = self.QueryGenerator.deleteQuery(tableName, identifier, null, instance.constructor);
options = _.clone(options) || {}; options = _.clone(options) || {};
// Check for a restrict field // Check for a restrict field
if (!!instance.Model && !!instance.Model.associations) { if (!!instance.constructor && !!instance.constructor.associations) {
var keys = Object.keys(instance.Model.associations) var keys = Object.keys(instance.constructor.associations)
, length = keys.length , length = keys.length
, association; , association;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
association = instance.Model.associations[keys[i]]; association = instance.constructor.associations[keys[i]];
if (association.options && association.options.onDelete && if (association.options && association.options.onDelete &&
association.options.onDelete.toLowerCase() === 'cascade' && association.options.onDelete.toLowerCase() === 'cascade' &&
association.options.useHooks === true) { association.options.useHooks === true) {
......
...@@ -14,7 +14,6 @@ var url = require('url') ...@@ -14,7 +14,6 @@ var url = require('url')
, sequelizeErrors = require('./errors') , sequelizeErrors = require('./errors')
, Promise = require('./promise') , Promise = require('./promise')
, Hooks = require('./hooks') , Hooks = require('./hooks')
, Instance = require('./instance')
, Association = require('./associations/index') , Association = require('./associations/index')
, _ = require('lodash'); , _ = require('lodash');
...@@ -328,13 +327,6 @@ Sequelize.prototype.Transaction = Sequelize.Transaction = Transaction; ...@@ -328,13 +327,6 @@ Sequelize.prototype.Transaction = Sequelize.Transaction = Transaction;
Sequelize.prototype.Deferrable = Sequelize.Deferrable = Deferrable; Sequelize.prototype.Deferrable = Sequelize.Deferrable = Deferrable;
/** /**
* A reference to the sequelize instance class.
* @property Instance
* @see {Instance}
*/
Sequelize.prototype.Instance = Sequelize.Instance = Instance;
/**
* A reference to the sequelize association class. * A reference to the sequelize association class.
* @property Association * @property Association
* @see {Association} * @see {Association}
...@@ -623,8 +615,9 @@ Sequelize.prototype.define = function(modelName, attributes, options) { // testh ...@@ -623,8 +615,9 @@ Sequelize.prototype.define = function(modelName, attributes, options) { // testh
modelName = options.modelName; modelName = options.modelName;
delete options.modelName; delete options.modelName;
var model = new Model(modelName, attributes, options); var model = class extends Model {};
model = model.init(this.modelManager); Object.defineProperty(model, 'name', {value: modelName});
model.init(attributes, options, this.modelManager);
this.modelManager.addModel(model); this.modelManager.addModel(model);
this.runHooks('afterDefine', model); this.runHooks('afterDefine', model);
...@@ -743,7 +736,7 @@ Sequelize.prototype.query = function(sql, options) { ...@@ -743,7 +736,7 @@ Sequelize.prototype.query = function(sql, options) {
options = _.assign({}, this.options.query, options); options = _.assign({}, this.options.query, options);
if (options.instance && !options.model) { if (options.instance && !options.model) {
options.model = options.instance.Model; options.model = options.instance.constructor;
} }
// Map raw fields to model field names using the `fieldAttributeMap` // Map raw fields to model field names using the `fieldAttributeMap`
......
...@@ -632,7 +632,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { ...@@ -632,7 +632,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
this.task = task; this.task = task;
return task.createUser({ username: 'foo' }); return task.createUser({ username: 'foo' });
}).then(function(createdUser) { }).then(function(createdUser) {
expect(createdUser.Model).to.equal(User); expect(createdUser).to.be.instanceof(User);
expect(createdUser.username).to.equal('foo'); expect(createdUser.username).to.equal('foo');
return this.task.getUsers(); return this.task.getUsers();
}).then(function(_users) { }).then(function(_users) {
...@@ -717,7 +717,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { ...@@ -717,7 +717,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
this.task = task; this.task = task;
return task.createUser({ username: 'foo' }, {fields: ['username']}); return task.createUser({ username: 'foo' }, {fields: ['username']});
}).then(function(createdUser) { }).then(function(createdUser) {
expect(createdUser.Model).to.equal(User); expect(createdUser).to.be.instanceof(User);
expect(createdUser.username).to.equal('foo'); expect(createdUser.username).to.equal('foo');
return this.task.getUsers(); return this.task.getUsers();
}).then(function(_users) { }).then(function(_users) {
......
...@@ -586,7 +586,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() { ...@@ -586,7 +586,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
// the `UPDATE` query generated by `save()` uses `id` in the // the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause // `WHERE` clause
var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.Model); var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.constructor);
return expect( return expect(
user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}) user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id})
).to.eventually.be.rejectedWith(Sequelize.ForeignKeyConstraintError).then(function () { ).to.eventually.be.rejectedWith(Sequelize.ForeignKeyConstraintError).then(function () {
...@@ -620,7 +620,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() { ...@@ -620,7 +620,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
// the `UPDATE` query generated by `save()` uses `id` in the // the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause // `WHERE` clause
var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.Model); var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.constructor);
return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}) return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id})
.then(function() { .then(function() {
return Task.findAll().then(function(tasks) { return Task.findAll().then(function(tasks) {
......
...@@ -1052,7 +1052,7 @@ describe(Support.getTestDialectTeaser('HasMany'), function() { ...@@ -1052,7 +1052,7 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
// the `UPDATE` query generated by `save()` uses `id` in the // the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause // `WHERE` clause
var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.Model); var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.constructor);
return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}); return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id});
}).then(function() { }).then(function() {
return Task.findAll(); return Task.findAll();
...@@ -1109,7 +1109,7 @@ describe(Support.getTestDialectTeaser('HasMany'), function() { ...@@ -1109,7 +1109,7 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
// the `UPDATE` query generated by `save()` uses `id` in the // the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause // `WHERE` clause
var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.Model); var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.constructor);
return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}) return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id})
.catch (self.sequelize.ForeignKeyConstraintError, function() { .catch (self.sequelize.ForeignKeyConstraintError, function() {
// Should fail due to FK violation // Should fail due to FK violation
......
...@@ -493,7 +493,7 @@ describe(Support.getTestDialectTeaser('HasOne'), function() { ...@@ -493,7 +493,7 @@ describe(Support.getTestDialectTeaser('HasOne'), function() {
// the `UPDATE` query generated by `save()` uses `id` in the // the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause // `WHERE` clause
var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.Model); var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.constructor);
return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}).then(function() { return user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}).then(function() {
return Task.findAll().then(function(tasks) { return Task.findAll().then(function(tasks) {
expect(tasks).to.have.length(1); expect(tasks).to.have.length(1);
...@@ -549,7 +549,7 @@ describe(Support.getTestDialectTeaser('HasOne'), function() { ...@@ -549,7 +549,7 @@ describe(Support.getTestDialectTeaser('HasOne'), function() {
// the `UPDATE` query generated by `save()` uses `id` in the // the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause // `WHERE` clause
var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.Model); var tableName = user.sequelize.getQueryInterface().QueryGenerator.addSchema(user.constructor);
return expect( return expect(
user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id}) user.sequelize.getQueryInterface().update(user, tableName, {id: 999}, {id: user.id})
).to.eventually.be.rejectedWith(Sequelize.ForeignKeyConstraintError).then(function () { ).to.eventually.be.rejectedWith(Sequelize.ForeignKeyConstraintError).then(function () {
......
...@@ -199,9 +199,9 @@ describe(Support.getTestDialectTeaser('associations'), function() { ...@@ -199,9 +199,9 @@ describe(Support.getTestDialectTeaser('associations'), function() {
questionComment.getItem() questionComment.getItem()
); );
}).spread(function(post, image, question) { }).spread(function(post, image, question) {
expect(post.Model).to.equal(self.Post); expect(post).to.be.instanceof(self.Post);
expect(image.Model).to.equal(self.Image); expect(image).to.be.instanceof(self.Image);
expect(question.Model).to.equal(self.Question); expect(question).to.be.instanceof(self.Question);
}).then(function() { }).then(function() {
return Promise.join( return Promise.join(
self.Post.find({ self.Post.find({
......
...@@ -113,12 +113,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() { ...@@ -113,12 +113,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() {
}, { }, {
hooks: { hooks: {
beforeValidate: function(user, options, fn) { beforeValidate: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
beforeHooked = true; beforeHooked = true;
fn(); fn();
}, },
afterValidate: function(user, options, fn) { afterValidate: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
afterHooked = true; afterHooked = true;
fn(); fn();
} }
...@@ -143,12 +143,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() { ...@@ -143,12 +143,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() {
}, { }, {
hooks: { hooks: {
beforeCreate: function(user, options, fn) { beforeCreate: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
beforeHooked = true; beforeHooked = true;
fn(); fn();
}, },
afterCreate: function(user, options, fn) { afterCreate: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
afterHooked = true; afterHooked = true;
fn(); fn();
} }
...@@ -173,12 +173,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() { ...@@ -173,12 +173,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() {
}, { }, {
hooks: { hooks: {
beforeDestroy: function(user, options, fn) { beforeDestroy: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
beforeHooked = true; beforeHooked = true;
fn(); fn();
}, },
afterDestroy: function(user, options, fn) { afterDestroy: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
afterHooked = true; afterHooked = true;
fn(); fn();
} }
...@@ -205,12 +205,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() { ...@@ -205,12 +205,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() {
}, { }, {
hooks: { hooks: {
beforeDelete: function(user, options, fn) { beforeDelete: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
beforeHooked = true; beforeHooked = true;
fn(); fn();
}, },
afterDelete: function(user, options, fn) { afterDelete: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
afterHooked = true; afterHooked = true;
fn(); fn();
} }
...@@ -237,12 +237,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() { ...@@ -237,12 +237,12 @@ describe(Support.getTestDialectTeaser('Hooks'), function() {
}, { }, {
hooks: { hooks: {
beforeUpdate: function(user, options, fn) { beforeUpdate: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
beforeHooked = true; beforeHooked = true;
fn(); fn();
}, },
afterUpdate: function(user, options, fn) { afterUpdate: function(user, options, fn) {
expect(user).to.be.instanceof(User.Instance); expect(user).to.be.instanceof(User);
afterHooked = true; afterHooked = true;
fn(); fn();
} }
......
...@@ -183,9 +183,9 @@ describe(Support.getTestDialectTeaser('DAO'), function() { ...@@ -183,9 +183,9 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
expect(product.tags).to.be.ok; expect(product.tags).to.be.ok;
expect(product.tags.length).to.equal(2); expect(product.tags.length).to.equal(2);
expect(product.tags[0].Model).to.equal(Tag); expect(product.tags[0]).to.be.instanceof(Tag);
expect(product.user).to.be.ok; expect(product.user).to.be.ok;
expect(product.user.Model).to.equal(User); expect(product.user).to.be.instanceof(User);
}); });
it('should support basic includes (with raw: true)', function() { it('should support basic includes (with raw: true)', function() {
...@@ -227,9 +227,9 @@ describe(Support.getTestDialectTeaser('DAO'), function() { ...@@ -227,9 +227,9 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
expect(product.tags).to.be.ok; expect(product.tags).to.be.ok;
expect(product.tags.length).to.equal(2); expect(product.tags.length).to.equal(2);
expect(product.tags[0].Model).to.equal(Tag); expect(product.tags[0]).to.be.instanceof(Tag);
expect(product.user).to.be.ok; expect(product.user).to.be.ok;
expect(product.user.Model).to.equal(User); expect(product.user).to.be.instanceof(User);
}); });
}); });
}); });
...@@ -350,8 +350,8 @@ describe(Support.getTestDialectTeaser('DAO'), function() { ...@@ -350,8 +350,8 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
} }
}, {raw: true}); }, {raw: true});
expect(product.get('user', {plain: true}).$Model).not.to.be.ok; expect(product.get('user', {plain: true})).not.to.be.instanceof(User);
expect(product.get({plain: true}).user.$Model).not.to.be.ok; expect(product.get({plain: true}).user).not.to.be.instanceof(User);
}); });
}); });
......
...@@ -623,9 +623,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -623,9 +623,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(product.Tags).to.be.ok; expect(product.Tags).to.be.ok;
expect(product.Tags.length).to.equal(2); expect(product.Tags.length).to.equal(2);
expect(product.Tags[0].Model).to.equal(Tag); expect(product.Tags[0]).to.be.instanceof(Tag);
expect(product.User).to.be.ok; expect(product.User).to.be.ok;
expect(product.User.Model).to.equal(User); expect(product.User).to.be.instanceof(User);
}); });
it('should support includes with aliases', function() { it('should support includes with aliases', function() {
...@@ -674,10 +674,10 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -674,10 +674,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(product.categories).to.be.ok; expect(product.categories).to.be.ok;
expect(product.categories.length).to.equal(4); expect(product.categories.length).to.equal(4);
expect(product.categories[0].Model).to.equal(Tag); expect(product.categories[0]).to.be.instanceof(Tag);
expect(product.followers).to.be.ok; expect(product.followers).to.be.ok;
expect(product.followers.length).to.equal(2); expect(product.followers.length).to.equal(2);
expect(product.followers[0].Model).to.equal(User); expect(product.followers[0]).to.be.instanceof(User);
}); });
}); });
}); });
......
...@@ -899,21 +899,21 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -899,21 +899,21 @@ describe(Support.getTestDialectTeaser('Model'), function() {
it('should return a DAO when queryOptions are not set', function() { it('should return a DAO when queryOptions are not set', function() {
var self = this; var self = this;
return this.User.findOne({ where: { username: 'barfooz'}}).then(function(user) { return this.User.findOne({ where: { username: 'barfooz'}}).then(function(user) {
expect(user).to.be.instanceOf(self.User.Instance); expect(user).to.be.instanceOf(self.User);
}); });
}); });
it('should return a DAO when raw is false', function() { it('should return a DAO when raw is false', function() {
var self = this; var self = this;
return this.User.findOne({ where: { username: 'barfooz'}, raw: false }).then(function(user) { return this.User.findOne({ where: { username: 'barfooz'}, raw: false }).then(function(user) {
expect(user).to.be.instanceOf(self.User.Instance); expect(user).to.be.instanceOf(self.User);
}); });
}); });
it('should return raw data when raw is true', function() { it('should return raw data when raw is true', function() {
var self = this; var self = this;
return this.User.findOne({ where: { username: 'barfooz'}, raw: true }).then(function(user) { return this.User.findOne({ where: { username: 'barfooz'}, raw: true }).then(function(user) {
expect(user).to.not.be.instanceOf(self.User.Instance); expect(user).to.not.be.instanceOf(self.User);
expect(user).to.be.instanceOf(Object); expect(user).to.be.instanceOf(Object);
}); });
}); });
......
...@@ -737,7 +737,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -737,7 +737,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var self = this; var self = this;
return this.User.findAll({ where: { username: 'barfooz'}}).then(function(users) { return this.User.findAll({ where: { username: 'barfooz'}}).then(function(users) {
users.forEach(function(user) { users.forEach(function(user) {
expect(user).to.be.instanceOf(self.User.Instance); expect(user).to.be.instanceOf(self.User);
}); });
}); });
}); });
...@@ -746,7 +746,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -746,7 +746,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var self = this; var self = this;
return this.User.findAll({ where: { username: 'barfooz'}, raw: false }).then(function(users) { return this.User.findAll({ where: { username: 'barfooz'}, raw: false }).then(function(users) {
users.forEach(function(user) { users.forEach(function(user) {
expect(user).to.be.instanceOf(self.User.Instance); expect(user).to.be.instanceOf(self.User);
}); });
}); });
}); });
...@@ -755,7 +755,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -755,7 +755,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var self = this; var self = this;
return this.User.findAll({ where: { username: 'barfooz'}, raw: true }).then(function(users) { return this.User.findAll({ where: { username: 'barfooz'}, raw: true }).then(function(users) {
users.forEach(function(user) { users.forEach(function(user) {
expect(user).to.not.be.instanceOf(self.User.Instance); expect(user).to.not.be.instanceOf(self.User);
expect(users[0]).to.be.instanceOf(Object); expect(users[0]).to.be.instanceOf(Object);
}); });
}); });
......
...@@ -393,7 +393,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() { ...@@ -393,7 +393,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
model: this.User model: this.User
}); });
}).then(function(users) { }).then(function(users) {
expect(users[0].Model).to.equal(this.User); expect(users[0]).to.be.instanceof(this.User);
}); });
}); });
......
...@@ -11,8 +11,8 @@ var QueryInterface = require(__dirname + '/../lib/query-interface') ...@@ -11,8 +11,8 @@ var QueryInterface = require(__dirname + '/../lib/query-interface')
module.exports = function(Sequelize) { module.exports = function(Sequelize) {
// Shim all Sequelize methods // Shim all Sequelize methods
shimAll(Sequelize.prototype); shimAll(Sequelize.prototype);
shimAll(Sequelize.Model);
shimAll(Sequelize.Model.prototype); shimAll(Sequelize.Model.prototype);
shimAll(Sequelize.Instance.prototype);
shimAll(QueryInterface.prototype); shimAll(QueryInterface.prototype);
// Shim Model.prototype to then shim getter/setter methods // Shim Model.prototype to then shim getter/setter methods
...@@ -23,7 +23,7 @@ module.exports = function(Sequelize) { ...@@ -23,7 +23,7 @@ module.exports = function(Sequelize) {
association = original.apply(this, arguments); association = original.apply(this, arguments);
_.forIn(association.accessors, function(accessor) { _.forIn(association.accessors, function(accessor) {
shim(model.Instance.prototype, accessor, model.Instance.prototype[accessor].length); shim(model.prototype, accessor, model.prototype[accessor].length);
}); });
return association; return association;
......
...@@ -429,10 +429,10 @@ describe(Support.getTestDialectTeaser('belongsToMany'), function() { ...@@ -429,10 +429,10 @@ describe(Support.getTestDialectTeaser('belongsToMany'), function() {
}); });
it('should work for belongsTo associations defined before belongsToMany', function () { it('should work for belongsTo associations defined before belongsToMany', function () {
expect(this.UserProjects.Instance.prototype.getUser).to.be.ok; expect(this.UserProjects.prototype.getUser).to.be.ok;
}); });
it('should work for belongsTo associations defined after belongsToMany', function () { it('should work for belongsTo associations defined after belongsToMany', function () {
expect(this.UserProjects.Instance.prototype.getProject).to.be.ok; expect(this.UserProjects.prototype.getProject).to.be.ok;
}); });
}); });
...@@ -484,22 +484,21 @@ describe(Support.getTestDialectTeaser('belongsToMany'), function() { ...@@ -484,22 +484,21 @@ describe(Support.getTestDialectTeaser('belongsToMany'), function() {
it('works with singular and plural name for self-associations', function () { it('works with singular and plural name for self-associations', function () {
// Models taken from https://github.com/sequelize/sequelize/issues/3796 // Models taken from https://github.com/sequelize/sequelize/issues/3796
var Service = current.define('service', {}) var Service = current.define('service', {});
, Instance = Service.Instance;
Service.belongsToMany(Service, {through: 'Supplements', as: 'supplements'}); Service.belongsToMany(Service, {through: 'Supplements', as: 'supplements'});
Service.belongsToMany(Service, {through: 'Supplements', as: {singular: 'supplemented', plural: 'supplemented'}}); Service.belongsToMany(Service, {through: 'Supplements', as: {singular: 'supplemented', plural: 'supplemented'}});
expect(Instance.prototype).to.have.property('getSupplements').which.is.a.function; expect(Service.prototype).to.have.property('getSupplements').which.is.a.function;
expect(Instance.prototype).to.have.property('addSupplement').which.is.a.function; expect(Service.prototype).to.have.property('addSupplement').which.is.a.function;
expect(Instance.prototype).to.have.property('addSupplements').which.is.a.function; expect(Service.prototype).to.have.property('addSupplements').which.is.a.function;
expect(Instance.prototype).to.have.property('getSupplemented').which.is.a.function; expect(Service.prototype).to.have.property('getSupplemented').which.is.a.function;
expect(Instance.prototype).not.to.have.property('getSupplementeds').which.is.a.function; expect(Service.prototype).not.to.have.property('getSupplementeds').which.is.a.function;
expect(Instance.prototype).to.have.property('addSupplemented').which.is.a.function; expect(Service.prototype).to.have.property('addSupplemented').which.is.a.function;
expect(Instance.prototype).not.to.have.property('addSupplementeds').which.is.a.function; expect(Service.prototype).not.to.have.property('addSupplementeds').which.is.a.function;
}); });
}); });
......
...@@ -12,14 +12,14 @@ var chai = require('chai') ...@@ -12,14 +12,14 @@ var chai = require('chai')
describe(Support.getTestDialectTeaser('Model'), function() { describe(Support.getTestDialectTeaser('Model'), function() {
describe('method findOne', function () { describe('method findOne', function () {
before(function () { before(function () {
this.oldFindAll = current.Model.prototype.findAll; this.oldFindAll = current.Model.findAll;
}); });
after(function () { after(function () {
current.Model.prototype.findAll = this.oldFindAll; current.Model.findAll = this.oldFindAll;
}); });
beforeEach(function () { beforeEach(function () {
this.stub = current.Model.prototype.findAll = sinon.stub().returns(Promise.resolve()); this.stub = current.Model.findAll = sinon.stub().returns(Promise.resolve());
}); });
describe('should not add limit when querying on a primary key', function () { describe('should not add limit when querying on a primary key', function () {
......
...@@ -298,7 +298,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -298,7 +298,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
limit: 9 limit: 9
}; };
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
...@@ -322,7 +322,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -322,7 +322,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var options = {}; var options = {};
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
...@@ -339,7 +339,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -339,7 +339,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
include: [{ model: Project, where: { something: true }}] include: [{ model: Project, where: { something: true }}]
}; };
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
...@@ -356,7 +356,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -356,7 +356,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
include: [{model: User, as: 'otherUser'}] include: [{model: User, as: 'otherUser'}]
}; };
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
...@@ -378,7 +378,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -378,7 +378,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
] ]
}; };
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
...@@ -401,7 +401,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -401,7 +401,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
] ]
}; };
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
...@@ -424,7 +424,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -424,7 +424,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
] ]
}; };
current.Model.prototype.$injectScope.call({ current.Model.$injectScope.call({
$scope: scope $scope: scope
}, options); }, options);
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!