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

Commit 1b4a7bf8 by Sushant Committed by GitHub

fix(association): use minimal select for hasAssociation (#10529)

1 parent 7ccbb1ea
...@@ -458,7 +458,7 @@ class BelongsToMany extends Association { ...@@ -458,7 +458,7 @@ class BelongsToMany extends Association {
/** /**
* Check if one or more instance(s) are associated with this. If a list of instances is passed, the function returns true if _all_ instances are associated * Check if one or more instance(s) are associated with this. If a list of instances is passed, the function returns true if _all_ instances are associated
* *
* @param {<Model>} sourceInstance source instance to associate new instances with * @param {<Model>} sourceInstance source instance to check for an association with
* @param {<Model>|<Model>[]|string[]|string|number[]|number} [instances] Can be an array of instances or their primary keys * @param {<Model>|<Model>[]|string[]|string|number[]|number} [instances] Can be an array of instances or their primary keys
* @param {Object} [options] Options passed to getAssociations * @param {Object} [options] Options passed to getAssociations
* *
...@@ -474,7 +474,9 @@ class BelongsToMany extends Association { ...@@ -474,7 +474,9 @@ class BelongsToMany extends Association {
options = Object.assign({ options = Object.assign({
raw: true raw: true
}, options, { }, options, {
scope: false scope: false,
attributes: [this.target.primaryKeyAttribute],
joinTableAttributes: []
}); });
where[Op.or] = instances.map(instance => { where[Op.or] = instances.map(instance => {
......
...@@ -284,6 +284,7 @@ class HasMany extends Association { ...@@ -284,6 +284,7 @@ class HasMany extends Association {
options = Object.assign({}, options, { options = Object.assign({}, options, {
scope: false, scope: false,
attributes: [this.target.primaryKeyAttribute],
raw: true raw: true
}); });
......
...@@ -414,6 +414,150 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -414,6 +414,150 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
}); });
}); });
describe('hasAssociations', () => {
beforeEach(function() {
this.Article = this.sequelize.define('Article', {
pk: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
title: DataTypes.STRING
});
this.Label = this.sequelize.define('Label', {
sk: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
text: DataTypes.STRING
});
this.ArticleLabel = this.sequelize.define('ArticleLabel');
this.Article.belongsToMany(this.Label, { through: this.ArticleLabel });
this.Label.belongsToMany(this.Article, { through: this.ArticleLabel });
return this.sequelize.sync({ force: true });
});
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
const ctx = {};
return Support.prepareTransactionTest(this.sequelize).then(sequelize => {
ctx.sequelize = sequelize;
ctx.Article = ctx.sequelize.define('Article', {
pk: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
title: DataTypes.STRING
});
ctx.Label = ctx.sequelize.define('Label', {
sk: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
text: DataTypes.STRING
});
ctx.ArticleLabel = ctx.sequelize.define('ArticleLabel');
ctx.Article.belongsToMany(ctx.Label, { through: ctx.ArticleLabel });
ctx.Label.belongsToMany(ctx.Article, { through: ctx.ArticleLabel });
return ctx.sequelize.sync({ force: true });
}).then(() => {
return Promise.all([
ctx.Article.create({ title: 'foo' }),
ctx.Label.create({ text: 'bar' })
]);
}).then(([article, label]) => {
ctx.article = article;
ctx.label = label;
return ctx.sequelize.transaction();
}).then(t => {
ctx.t = t;
return ctx.article.setLabels([ctx.label], { transaction: t });
}).then(() => {
return ctx.Article.findAll({ transaction: ctx.t });
}).then(articles => {
return Promise.all([
articles[0].hasLabels([ctx.label]),
articles[0].hasLabels([ctx.label], { transaction: ctx.t })
]);
}).then(([hasLabel1, hasLabel2]) => {
expect(hasLabel1).to.be.false;
expect(hasLabel2).to.be.true;
return ctx.t.rollback();
});
});
}
it('answers false if only some labels have been assigned', function() {
return Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => {
return article.addLabel(label1).then(() => {
return article.hasLabels([label1, label2]);
});
}).then(result => {
expect(result).to.be.false;
});
});
it('answers false if only some labels have been assigned when passing a primary key instead of an object', function() {
return Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => {
return article.addLabels([label1]).then(() => {
return article.hasLabels([
label1[this.Label.primaryKeyAttribute],
label2[this.Label.primaryKeyAttribute]
]).then(result => {
expect(result).to.be.false;
});
});
});
});
it('answers true if all label have been assigned', function() {
return Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => {
return article.setLabels([label1, label2]).then(() => {
return article.hasLabels([label1, label2]).then(result => {
expect(result).to.be.true;
});
});
});
});
it('answers true if all label have been assigned when passing a primary key instead of an object', function() {
return Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => {
return article.setLabels([label1, label2]).then(() => {
return article.hasLabels([
label1[this.Label.primaryKeyAttribute],
label2[this.Label.primaryKeyAttribute]
]).then(result => {
expect(result).to.be.true;
});
});
});
});
});
describe('countAssociations', () => { describe('countAssociations', () => {
beforeEach(function() { beforeEach(function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
...@@ -1543,7 +1687,6 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -1543,7 +1687,6 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
}); });
}); });
describe('primary key handling for join table', () => { describe('primary key handling for join table', () => {
beforeEach(function() { beforeEach(function() {
this.User = this.sequelize.define('User', this.User = this.sequelize.define('User',
......
...@@ -443,10 +443,25 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -443,10 +443,25 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
}); });
describe('(1:N)', () => { describe('(1:N)', () => {
describe('hasSingle', () => { describe('hasAssociation', () => {
beforeEach(function() { beforeEach(function() {
this.Article = this.sequelize.define('Article', { 'title': DataTypes.STRING }); this.Article = this.sequelize.define('Article', {
this.Label = this.sequelize.define('Label', { 'text': DataTypes.STRING }); pk: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
title: DataTypes.STRING
});
this.Label = this.sequelize.define('Label', {
key: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
text: DataTypes.STRING
});
this.Article.hasMany(this.Label); this.Article.hasMany(this.Label);
...@@ -546,8 +561,8 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -546,8 +561,8 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
]).then(([article, label1, label2]) => { ]).then(([article, label1, label2]) => {
return article.addLabel(label1).then(() => { return article.addLabel(label1).then(() => {
return Promise.all([ return Promise.all([
article.hasLabel(label1.id), article.hasLabel(label1[this.Label.primaryKeyAttribute]),
article.hasLabel(label2.id) article.hasLabel(label2[this.Label.primaryKeyAttribute])
]); ]);
}); });
}).then(([hasLabel1, hasLabel2]) => { }).then(([hasLabel1, hasLabel2]) => {
...@@ -557,13 +572,24 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -557,13 +572,24 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
}); });
}); });
describe('hasAll', () => { describe('hasAssociations', () => {
beforeEach(function() { beforeEach(function() {
this.Article = this.sequelize.define('Article', { this.Article = this.sequelize.define('Article', {
'title': DataTypes.STRING pk: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
title: DataTypes.STRING
}); });
this.Label = this.sequelize.define('Label', { this.Label = this.sequelize.define('Label', {
'text': DataTypes.STRING key: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
text: DataTypes.STRING
}); });
this.Article.hasMany(this.Label); this.Article.hasMany(this.Label);
...@@ -631,7 +657,10 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -631,7 +657,10 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
this.Label.create({ text: 'Epicness' }) this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => { ]).then(([article, label1, label2]) => {
return article.addLabel(label1).then(() => { return article.addLabel(label1).then(() => {
return article.hasLabels([label1.id, label2.id]).then(result => { return article.hasLabels([
label1[this.Label.primaryKeyAttribute],
label2[this.Label.primaryKeyAttribute]
]).then(result => {
expect(result).to.be.false; expect(result).to.be.false;
}); });
}); });
...@@ -659,7 +688,10 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -659,7 +688,10 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
this.Label.create({ text: 'Epicness' }) this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => { ]).then(([article, label1, label2]) => {
return article.setLabels([label1, label2]).then(() => { return article.setLabels([label1, label2]).then(() => {
return article.hasLabels([label1.id, label2.id]).then(result => { return article.hasLabels([
label1[this.Label.primaryKeyAttribute],
label2[this.Label.primaryKeyAttribute]
]).then(result => {
expect(result).to.be.true; expect(result).to.be.true;
}); });
}); });
...@@ -668,7 +700,6 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -668,7 +700,6 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
}); });
describe('setAssociations', () => { describe('setAssociations', () => {
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', function() {
const ctx = {}; const ctx = {};
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!