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

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 {
/**
* 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 {Object} [options] Options passed to getAssociations
*
......@@ -474,7 +474,9 @@ class BelongsToMany extends Association {
options = Object.assign({
raw: true
}, options, {
scope: false
scope: false,
attributes: [this.target.primaryKeyAttribute],
joinTableAttributes: []
});
where[Op.or] = instances.map(instance => {
......
......@@ -284,6 +284,7 @@ class HasMany extends Association {
options = Object.assign({}, options, {
scope: false,
attributes: [this.target.primaryKeyAttribute],
raw: true
});
......
......@@ -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', () => {
beforeEach(function() {
this.User = this.sequelize.define('User', {
......@@ -1543,7 +1687,6 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
});
});
describe('primary key handling for join table', () => {
beforeEach(function() {
this.User = this.sequelize.define('User',
......
......@@ -443,10 +443,25 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
});
describe('(1:N)', () => {
describe('hasSingle', () => {
describe('hasAssociation', () => {
beforeEach(function() {
this.Article = this.sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = this.sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article = this.sequelize.define('Article', {
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);
......@@ -546,8 +561,8 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
]).then(([article, label1, label2]) => {
return article.addLabel(label1).then(() => {
return Promise.all([
article.hasLabel(label1.id),
article.hasLabel(label2.id)
article.hasLabel(label1[this.Label.primaryKeyAttribute]),
article.hasLabel(label2[this.Label.primaryKeyAttribute])
]);
});
}).then(([hasLabel1, hasLabel2]) => {
......@@ -557,13 +572,24 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
});
});
describe('hasAll', () => {
describe('hasAssociations', () => {
beforeEach(function() {
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', {
'text': DataTypes.STRING
key: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
text: DataTypes.STRING
});
this.Article.hasMany(this.Label);
......@@ -631,7 +657,10 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => {
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;
});
});
......@@ -659,7 +688,10 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
this.Label.create({ text: 'Epicness' })
]).then(([article, label1, label2]) => {
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;
});
});
......@@ -668,7 +700,6 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
});
describe('setAssociations', () => {
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
const ctx = {};
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!