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

Commit ce9287fe by Takashi Sasaki Committed by Sushant

fix(association): enable eager load with include all(#9928) (#10173)

1 parent 9ba5f3c2
...@@ -755,6 +755,18 @@ class BelongsToMany extends Association { ...@@ -755,6 +755,18 @@ class BelongsToMany extends Association {
sourceInstance[association.accessors.add](newAssociatedObject, _.omit(options, ['fields'])).return(newAssociatedObject) sourceInstance[association.accessors.add](newAssociatedObject, _.omit(options, ['fields'])).return(newAssociatedObject)
); );
} }
verifyAssociationAlias(alias) {
if (typeof alias === 'string') {
return this.as === alias;
}
if (alias && alias.plural) {
return this.as === alias.plural;
}
return !this.isAliased;
}
} }
module.exports = BelongsToMany; module.exports = BelongsToMany;
......
...@@ -231,6 +231,18 @@ class BelongsTo extends Association { ...@@ -231,6 +231,18 @@ class BelongsTo extends Association {
.then(() => newAssociatedObject) .then(() => newAssociatedObject)
); );
} }
verifyAssociationAlias(alias) {
if (typeof alias === 'string') {
return this.as === alias;
}
if (alias && alias.singular) {
return this.as === alias.singular;
}
return !this.isAliased;
}
} }
module.exports = BelongsTo; module.exports = BelongsTo;
......
...@@ -463,6 +463,18 @@ class HasMany extends Association { ...@@ -463,6 +463,18 @@ class HasMany extends Association {
if (options.fields) options.fields.push(this.foreignKey); if (options.fields) options.fields.push(this.foreignKey);
return this.target.create(values, options); return this.target.create(values, options);
} }
verifyAssociationAlias(alias) {
if (typeof alias === 'string') {
return this.as === alias;
}
if (alias && alias.plural) {
return this.as === alias.plural;
}
return !this.isAliased;
}
} }
module.exports = HasMany; module.exports = HasMany;
......
...@@ -261,6 +261,18 @@ class HasOne extends Association { ...@@ -261,6 +261,18 @@ class HasOne extends Association {
return this.target.create(values, options); return this.target.create(values, options);
} }
verifyAssociationAlias(alias) {
if (typeof alias === 'string') {
return this.as === alias;
}
if (alias && alias.singular) {
return this.as === alias.singular;
}
return !this.isAliased;
}
} }
module.exports = HasOne; module.exports = HasOne;
...@@ -80,14 +80,7 @@ const Mixin = { ...@@ -80,14 +80,7 @@ const Mixin = {
getAssociationForAlias(target, alias) { getAssociationForAlias(target, alias) {
// Two associations cannot have the same alias, so we can use find instead of filter // Two associations cannot have the same alias, so we can use find instead of filter
return this.getAssociations(target).find(association => this.verifyAssociationAlias(association, alias)) || null; return this.getAssociations(target).find(association => association.verifyAssociationAlias(alias)) || null;
},
verifyAssociationAlias(association, alias) {
if (alias) {
return association.as === alias;
}
return !association.isAliased;
} }
}; };
......
...@@ -2423,4 +2423,86 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -2423,4 +2423,86 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
expect(PersonChildren.rawAttributes[Children.otherKey].field).to.equal('child_id'); expect(PersonChildren.rawAttributes[Children.otherKey].field).to.equal('child_id');
}); });
}); });
describe('Eager loading', () => {
beforeEach(function() {
this.Individual = this.sequelize.define('individual', {
name: Sequelize.STRING
});
this.Hat = this.sequelize.define('hat', {
name: Sequelize.STRING
});
this.Event = this.sequelize.define('event', {});
this.Individual.belongsToMany(this.Hat, {
through: this.Event,
as: {
singular: 'personwearinghat',
plural: 'personwearinghats'
}
});
this.Hat.belongsToMany(this.Individual, {
through: this.Event,
as: {
singular: 'hatwornby',
plural: 'hatwornbys'
}
});
});
it('should load with an alias', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.addPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{model: this.Hat, as: 'personwearinghats' }]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghats.length).to.equal(1);
expect(individual.personwearinghats[0].name).to.equal('Baz');
}).then(() => {
return this.Hat.findOne({
where: {name: 'Baz'},
include: [{model: this.Individual, as: 'hatwornbys'}]
});
}).then(hat => {
expect(hat.name).to.equal('Baz');
expect(hat.hatwornbys.length).to.equal(1);
expect(hat.hatwornbys[0].name).to.equal('Foo Bar');
});
});
it('should load all', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.addPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{all: true}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghats.length).to.equal(1);
expect(individual.personwearinghats[0].name).to.equal('Baz');
}).then(() => {
return this.Hat.findOne({
where: {name: 'Baz'},
include: [{all: true}]
});
}).then(hat => {
expect(hat.name).to.equal('Baz');
expect(hat.hatwornbys.length).to.equal(1);
expect(hat.hatwornbys[0].name).to.equal('Foo Bar');
});
});
});
}); });
...@@ -975,4 +975,65 @@ describe(Support.getTestDialectTeaser('BelongsTo'), () => { ...@@ -975,4 +975,65 @@ describe(Support.getTestDialectTeaser('BelongsTo'), () => {
.throw ('Naming collision between attribute \'person\' and association \'person\' on model car. To remedy this, change either foreignKey or as in your association definition'); .throw ('Naming collision between attribute \'person\' and association \'person\' on model car. To remedy this, change either foreignKey or as in your association definition');
}); });
}); });
describe('Eager loading', () => {
beforeEach(function() {
this.Individual = this.sequelize.define('individual', {
name: Sequelize.STRING
});
this.Hat = this.sequelize.define('hat', {
name: Sequelize.STRING
});
this.Individual.belongsTo(this.Hat, {
as: 'personwearinghat'
});
});
it('should load with an alias', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.setPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{model: this.Hat, as: 'personwearinghat'}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghat.name).to.equal('Baz');
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{
model: this.Hat,
as: {singular: 'personwearinghat'}
}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghat.name).to.equal('Baz');
});
});
it('should load all', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.setPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{all: true}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghat.name).to.equal('Baz');
});
});
});
}); });
...@@ -1601,4 +1601,59 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { ...@@ -1601,4 +1601,59 @@ describe(Support.getTestDialectTeaser('HasMany'), () => {
}); });
}); });
}); });
describe('Eager loading', () => {
beforeEach(function() {
this.Individual = this.sequelize.define('individual', {
name: Sequelize.STRING
});
this.Hat = this.sequelize.define('hat', {
name: Sequelize.STRING
});
this.Individual.hasMany(this.Hat, {
as: {
singular: 'personwearinghat',
plural: 'personwearinghats'
}
});
});
it('should load with an alias', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.addPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{model: this.Hat, as: 'personwearinghats'}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghats.length).to.equal(1);
expect(individual.personwearinghats[0].name).to.equal('Baz');
});
});
it('should load all', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.addPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{all: true}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghats.length).to.equal(1);
expect(individual.personwearinghats[0].name).to.equal('Baz');
});
});
});
}); });
...@@ -884,4 +884,65 @@ describe(Support.getTestDialectTeaser('HasOne'), () => { ...@@ -884,4 +884,65 @@ describe(Support.getTestDialectTeaser('HasOne'), () => {
}); });
}); });
}); });
describe('Eager loading', () => {
beforeEach(function() {
this.Individual = this.sequelize.define('individual', {
name: Sequelize.STRING
});
this.Hat = this.sequelize.define('hat', {
name: Sequelize.STRING
});
this.Individual.hasOne(this.Hat, {
as: 'personwearinghat'
});
});
it('should load with an alias', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.setPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{model: this.Hat, as: 'personwearinghat'}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghat.name).to.equal('Baz');
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{
model: this.Hat,
as: {singular: 'personwearinghat'}
}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghat.name).to.equal('Baz');
});
});
it('should load all', function() {
return this.sequelize.sync({force: true}).then(() => {
return Promise.join(
this.Individual.create({name: 'Foo Bar'}),
this.Hat.create({name: 'Baz'}));
}).then(([individual, hat]) => {
return individual.setPersonwearinghat(hat);
}).then(() => {
return this.Individual.findOne({
where: {name: 'Foo Bar'},
include: [{all: true}]
});
}).then(individual => {
expect(individual.name).to.equal('Foo Bar');
expect(individual.personwearinghat.name).to.equal('Baz');
});
});
});
}); });
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!