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

Commit 538a095e by Jan Aagaard Meier

bug(scope) Handle scope on an included model properly. Closes #3700

1 parent c9edd420
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
- [FIXED] Call `conformOptions` on scopes returned by functions [#3991](https://github.com/sequelize/sequelize/issues/3991) - [FIXED] Call `conformOptions` on scopes returned by functions [#3991](https://github.com/sequelize/sequelize/issues/3991)
- [FIXED] Calling `validateIncludedElements` should not add an aliassed primary key multiple times [#4127](https://github.com/sequelize/sequelize/issues/4127) - [FIXED] Calling `validateIncludedElements` should not add an aliassed primary key multiple times [#4127](https://github.com/sequelize/sequelize/issues/4127)
- [FEATURE] `addScope` [#3963](https://github.com/sequelize/sequelize/issues/3963) - [FEATURE] `addScope` [#3963](https://github.com/sequelize/sequelize/issues/3963)
- [FIXED] Handle scoped model in includes properly [#3700](https://github.com/sequelize/sequelize/issues/3700)
# 3.4.1 # 3.4.1
- [FIXED] Fix belongs-to-many `countAssociations` - ambigious id when through model has id - [FIXED] Fix belongs-to-many `countAssociations` - ambigious id when through model has id
......
...@@ -243,10 +243,6 @@ function conformOptions(options, self) { ...@@ -243,10 +243,6 @@ function conformOptions(options, self) {
options.include = options.include.map(function(include) { options.include = options.include.map(function(include) {
include = conformInclude(include, self); include = conformInclude(include, self);
if (!include.all) {
_.defaults(include, include.model.$scope);
}
return include; return include;
}); });
} }
...@@ -581,6 +577,18 @@ validateIncludedElement = function(include, tableNames, options) { ...@@ -581,6 +577,18 @@ validateIncludedElement = function(include, tableNames, options) {
tableNames[through.tableName] = true; tableNames[through.tableName] = true;
} }
// include.model may be the main model, while the association target may be scoped - thus we need to look at association.target/source
var model;
if (include.model.scoped === true) {
// If the passed model is already scoped, keep that
model = include.model;
} else {
// Otherwise use the model that was originally passed to the association
model = include.association.target.name === include.model.name ? include.association.target : include.association.source;
}
Model.$injectScope(model.$scope, include);
if (include.required === undefined) { if (include.required === undefined) {
include.required = !!include.where; include.required = !!include.where;
} }
...@@ -1140,6 +1148,8 @@ Model.prototype.scope = function(option) { ...@@ -1140,6 +1148,8 @@ Model.prototype.scope = function(option) {
} }
}); });
self.scoped = true;
return self; return self;
}; };
......
...@@ -96,7 +96,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -96,7 +96,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
this.ScopeMe.hasOne(this.Profile, { foreignKey: 'userId' }); this.ScopeMe.hasOne(this.Profile, { foreignKey: 'userId' });
this.ScopeMe.belongsTo(this.Company); this.ScopeMe.belongsTo(this.Company);
this.UserAssociation = this.Company.hasMany(this.ScopeMe, { as: 'users'}); this.UserAssociation = this.Company.hasMany(this.ScopeMe, { as: 'users' });
return this.sequelize.sync({force: true}).bind(this).then(function() { return this.sequelize.sync({force: true}).bind(this).then(function() {
return Promise.all([ return Promise.all([
......
...@@ -68,6 +68,67 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -68,6 +68,67 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
}); });
describe('scope', function () {
beforeEach(function () {
this.Project = this.sequelize.define('project', {}, {
defaultScope: {
where: {
active: true
}
}, scopes: {
this: {
where: { this: true}
},
that: {
where: { that: false },
limit: 12
}
}
});
this.User.hasMany(this.Project);
this.User.hasMany(this.Project.scope('this'), { as: 'thisProject' });
});
it('adds the default scope to where', function () {
var options = Sequelize.Model.$validateIncludedElements({
model: this.User,
include: [{ model: this.Project }]
});
expect(options.include[0]).to.have.property('where').which.deep.equals({ active: true });
});
it('adds the where from a scoped model', function () {
var options = Sequelize.Model.$validateIncludedElements({
model: this.User,
include: [{ model: this.Project.scope('that') }]
});
expect(options.include[0]).to.have.property('where').which.deep.equals({ that: false });
expect(options.include[0]).to.have.property('limit').which.equals(12);
});
it('merges where with the where from a scoped model', function () {
var options = Sequelize.Model.$validateIncludedElements({
model: this.User,
include: [{ where: { active: false }, model: this.Project.scope('that') }]
});
expect(options.include[0]).to.have.property('where').which.deep.equals({ active: false, that: false });
});
it('add the where from a scoped associated model', function () {
var options = Sequelize.Model.$validateIncludedElements({
model: this.User,
include: [{ model: this.Project, as: 'thisProject' }]
});
expect(options.include[0]).to.have.property('where').which.deep.equals({ this: true });
});
});
describe('duplicating', function () { describe('duplicating', function () {
it('should tag a hasMany association as duplicating: true if undefined', function () { it('should tag a hasMany association as duplicating: true if undefined', function () {
var options = Sequelize.Model.$validateIncludedElements({ var options = Sequelize.Model.$validateIncludedElements({
......
...@@ -205,7 +205,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -205,7 +205,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
include: [Project] include: [Project]
}, { override: true }); }, { override: true });
console.log(Company.$scope);
expect(Company.$scope).to.deep.equal({ expect(Company.$scope).to.deep.equal({
include: [{ model: Project }] include: [{ model: Project }]
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!