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

Commit b0aa1063 by Verdier

Fix $injectScope to not insert include twice

1 parent b2d8f5f2
Showing with 52 additions and 41 deletions
...@@ -236,23 +236,21 @@ function conformOptions(options, self) { ...@@ -236,23 +236,21 @@ function conformOptions(options, self) {
self.$expandAttributes(options); self.$expandAttributes(options);
} }
if (!options.include) { if (options.include) {
return; // if include is not an array, wrap in an array
} if (!Array.isArray(options.include)) {
// if include is not an array, wrap in an array options.include = [options.include];
if (!Array.isArray(options.include)) { }
options.include = [options.include];
} else if (!options.include.length) {
delete options.include;
return;
}
// convert all included elements to { model: Model } form // convert all included elements to { model: Model } form
options.include = options.include.map(function(include) { options.include = options.include.map(function(include) {
include = conformInclude(include, self); return conformInclude(include, self);
});
return include; if (!options.include.length) {
}); delete options.include;
}
}
} }
Model.$conformOptions = conformOptions; Model.$conformOptions = conformOptions;
...@@ -601,7 +599,7 @@ validateIncludedElement = function(include, tableNames, options) { ...@@ -601,7 +599,7 @@ validateIncludedElement = function(include, tableNames, options) {
model = include.association.target.name === include.model.name ? include.association.target : include.association.source; model = include.association.target.name === include.model.name ? include.association.target : include.association.source;
} }
Model.$injectScope(model.$scope, include); model.$injectScope(include);
// This check should happen after injecting the scope, since the scope may contain a .attributes // This check should happen after injecting the scope, since the scope may contain a .attributes
if (!include.attributes) { if (!include.attributes) {
...@@ -1328,7 +1326,7 @@ Model.prototype.findAll = function(options) { ...@@ -1328,7 +1326,7 @@ Model.prototype.findAll = function(options) {
return Promise.bind(this).then(function() { return Promise.bind(this).then(function() {
conformOptions(options, this); conformOptions(options, this);
Model.$injectScope(this.$scope, options); this.$injectScope(options);
if (options.hooks) { if (options.hooks) {
return this.runHooks('beforeFind', options); return this.runHooks('beforeFind', options);
...@@ -1511,7 +1509,7 @@ Model.prototype.find = Model.prototype.findOne; ...@@ -1511,7 +1509,7 @@ Model.prototype.find = Model.prototype.findOne;
Model.prototype.aggregate = function(attribute, aggregateFunction, options) { Model.prototype.aggregate = function(attribute, aggregateFunction, options) {
options = Utils._.extend({ attributes: [] }, options || {}); options = Utils._.extend({ attributes: [] }, options || {});
conformOptions(options, this); conformOptions(options, this);
Model.$injectScope(this.$scope, options); this.$injectScope(options);
var attrOptions = this.rawAttributes[attribute] var attrOptions = this.rawAttributes[attribute]
, field = attrOptions && attrOptions.field || attribute , field = attrOptions && attrOptions.field || attribute
...@@ -1559,7 +1557,7 @@ Model.prototype.aggregate = function(attribute, aggregateFunction, options) { ...@@ -1559,7 +1557,7 @@ Model.prototype.aggregate = function(attribute, aggregateFunction, options) {
Model.prototype.count = function(options) { Model.prototype.count = function(options) {
options = Utils._.clone(options || {}); options = Utils._.clone(options || {});
conformOptions(options, this); conformOptions(options, this);
Model.$injectScope(this.$scope, options); this.$injectScope(options);
var col = '*'; var col = '*';
...@@ -2242,7 +2240,7 @@ Model.prototype.destroy = function(options) { ...@@ -2242,7 +2240,7 @@ Model.prototype.destroy = function(options) {
}, options || {}); }, options || {});
options.type = QueryTypes.BULKDELETE; options.type = QueryTypes.BULKDELETE;
Model.$injectScope(this.$scope, options); this.$injectScope(options);
Utils.mapOptionFieldNames(options, this); Utils.mapOptionFieldNames(options, this);
...@@ -2402,7 +2400,7 @@ Model.prototype.update = function(values, options) { ...@@ -2402,7 +2400,7 @@ Model.prototype.update = function(values, options) {
options.type = QueryTypes.BULKUPDATE; options.type = QueryTypes.BULKUPDATE;
Model.$injectScope(this.$scope, options); this.$injectScope(options);
// Clone values so it doesn't get modified for caller scope // Clone values so it doesn't get modified for caller scope
values = _.clone(values); values = _.clone(values);
...@@ -2606,13 +2604,10 @@ Model.prototype.$expandAttributes = function (options) { ...@@ -2606,13 +2604,10 @@ Model.prototype.$expandAttributes = function (options) {
} }
}; };
// Inject current scope into options. Includes should have been conformed (conformOptions) before calling this // Inject $scope into options. Includes should have been conformed (conformOptions) before calling this
Model.$injectScope = function (scope, options) { Model.prototype.$injectScope = function (options) {
// Do not inject scope more than once. var self = this;
if (options._scopeInjected) return; var scope = optClone(this.$scope);
options._scopeInjected = true;
scope = optClone(scope);
var filteredScope = _.omit(scope, 'include'); // Includes need special treatment var filteredScope = _.omit(scope, 'include'); // Includes need special treatment
...@@ -2623,15 +2618,18 @@ Model.$injectScope = function (scope, options) { ...@@ -2623,15 +2618,18 @@ Model.$injectScope = function (scope, options) {
options.include = options.include || []; options.include = options.include || [];
// Reverse so we consider the latest include first. // Reverse so we consider the latest include first.
// This is used if several scopes specify the same include - the last scope should take precendence // This is used if several scopes specify the same include - the last scope should take precedence
scope.include.reverse().forEach(function (scopeInclude) { scope.include.reverse().forEach(function (scopeInclude) {
if (scopeInclude.all || !_.any(options.include, function matchesModelAndAlias(item) { if (scopeInclude.all || !options.include.some(function matchesModelAndAlias(item) {
var sameModel = item.model && item.model.name === scopeInclude.model.name; var isSameModel = item.model && item.model.name === scopeInclude.model.name;
if (!isSameModel || !item.as) return isSameModel;
if (sameModel && item.as) { if (scopeInclude.as) {
return item.as === scopeInclude.as; return item.as === scopeInclude.as;
} else {
var association = scopeInclude.association || self.getAssociation(scopeInclude.model, scopeInclude.as);
return association ? item.as === association.as : false;
} }
return sameModel;
})) { })) {
options.include.push(scopeInclude); options.include.push(scopeInclude);
} }
......
...@@ -253,8 +253,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -253,8 +253,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
limit: 9 limit: 9
}; };
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
delete options._scopeInjected; $scope: scope
}, options);
expect(options).to.deep.equal({ expect(options).to.deep.equal({
where: { where: {
...@@ -276,7 +277,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -276,7 +277,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var options = {}; var options = {};
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
$scope: scope
}, options);
expect(options.include).to.have.length(1); expect(options.include).to.have.length(1);
expect(options.include[0]).to.deep.equal({ model: Project, where: { something: true }}); expect(options.include[0]).to.deep.equal({ model: Project, where: { something: true }});
...@@ -291,7 +294,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -291,7 +294,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
include: [{ model: Project, where: { something: true }}] include: [{ model: Project, where: { something: true }}]
}; };
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
$scope: scope
}, options);
expect(options.include).to.have.length(1); expect(options.include).to.have.length(1);
expect(options.include[0]).to.deep.equal({ model: Project, where: { something: true }}); expect(options.include[0]).to.deep.equal({ model: Project, where: { something: true }});
...@@ -306,7 +311,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -306,7 +311,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
include: [{model: User, as: 'otherUser'}] include: [{model: User, as: 'otherUser'}]
}; };
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
$scope: scope
}, options);
expect(options.include).to.have.length(2); expect(options.include).to.have.length(2);
expect(options.include[0]).to.deep.equal({model: User, as: 'otherUser'}); expect(options.include[0]).to.deep.equal({model: User, as: 'otherUser'});
...@@ -326,7 +333,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -326,7 +333,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
] ]
}; };
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
$scope: scope
}, options);
expect(options.include).to.have.length(2); expect(options.include).to.have.length(2);
expect(options.include[0]).to.deep.equal({ model: User, where: { something: true }}); expect(options.include[0]).to.deep.equal({ model: User, where: { something: true }});
...@@ -347,7 +356,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -347,7 +356,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
] ]
}; };
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
$scope: scope
}, options);
expect(options.include).to.have.length(2); expect(options.include).to.have.length(2);
expect(options.include[0]).to.deep.equal({ model: User, where: { something: true }}); expect(options.include[0]).to.deep.equal({ model: User, where: { something: true }});
...@@ -368,7 +379,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -368,7 +379,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
] ]
}; };
current.Model.$injectScope(scope, options); current.Model.prototype.$injectScope.call({
$scope: scope
}, options);
expect(options.include).to.have.length(2); expect(options.include).to.have.length(2);
expect(options.include[0]).to.deep.equal({ all: true }); expect(options.include[0]).to.deep.equal({ all: true });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!