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

Commit 5dc314b5 by Takashi Sasaki Committed by Sushant

fix(model): create instance with many-to-many association with extra column (#10034) (#10050)

1 parent 9857f362
...@@ -3809,7 +3809,8 @@ class Model { ...@@ -3809,7 +3809,8 @@ class Model {
if (!this._options.include || !this._options.include.length) return this; if (!this._options.include || !this._options.include.length) return this;
// Nested creation for HasOne/HasMany/BelongsToMany relations // Nested creation for HasOne/HasMany/BelongsToMany relations
return Promise.map(this._options.include.filter(include => !(include.association instanceof BelongsTo)), include => { return Promise.map(this._options.include.filter(include => !(include.association instanceof BelongsTo ||
include.parent && include.parent.association instanceof BelongsToMany)), include => {
let instances = this.get(include.as); let instances = this.get(include.as);
if (!instances) return Promise.resolve(); if (!instances) return Promise.resolve();
...@@ -3831,8 +3832,21 @@ class Model { ...@@ -3831,8 +3832,21 @@ class Model {
const values = {}; const values = {};
values[include.association.foreignKey] = this.get(this.constructor.primaryKeyAttribute, {raw: true}); values[include.association.foreignKey] = this.get(this.constructor.primaryKeyAttribute, {raw: true});
values[include.association.otherKey] = instance.get(instance.constructor.primaryKeyAttribute, {raw: true}); values[include.association.otherKey] = instance.get(instance.constructor.primaryKeyAttribute, {raw: true});
// Include values defined in the scope of the association
// Include values defined in the association
Object.assign(values, include.association.through.scope); Object.assign(values, include.association.through.scope);
if (instance[include.association.through.model.name]) {
for (const attr of Object.keys(include.association.through.model.rawAttributes)) {
if (include.association.through.model.rawAttributes[attr]._autoGenerated ||
attr === include.association.foreignKey ||
attr === include.association.otherKey ||
typeof instance[include.association.through.model.name][attr] === undefined) {
continue;
}
values[attr] = instance[include.association.through.model.name][attr];
}
}
return include.association.throughModel.create(values, includeOptions); return include.association.throughModel.create(values, includeOptions);
}); });
} else { } else {
......
...@@ -1786,6 +1786,44 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -1786,6 +1786,44 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
return ctx.worker.addTask(ctx.task); return ctx.worker.addTask(ctx.task);
}); });
}); });
it('should be able to create an instance along with its many-to-many association which has an extra column in the junction table', function() {
const Foo = this.sequelize.define('foo', { name: Sequelize.STRING });
const Bar = this.sequelize.define('bar', { name: Sequelize.STRING });
const FooBar = this.sequelize.define('foobar', { baz: Sequelize.STRING });
Foo.belongsToMany(Bar, { through: FooBar });
Bar.belongsToMany(Foo, { through: FooBar });
return this.sequelize.sync({force: true}).then(() => {
return Foo.create({
name: 'foo...',
bars: [
{
name: 'bar...',
foobar: {
baz: 'baz...'
}
}
]
}, {
include: Bar
});
}).then(foo => {
expect(foo.name).to.equal('foo...');
expect(foo.bars).to.have.length(1);
expect(foo.bars[0].name).to.equal('bar...');
expect(foo.bars[0].foobar).to.not.equal(null);
expect(foo.bars[0].foobar.baz).to.equal('baz...');
return Foo.findOne({ include: Bar });
}).then(foo => {
expect(foo.name).to.equal('foo...');
expect(foo.bars).to.have.length(1);
expect(foo.bars[0].name).to.equal('bar...');
expect(foo.bars[0].foobar).to.not.equal(null);
expect(foo.bars[0].foobar.baz).to.equal('baz...');
});
});
}); });
describe('set', () => { describe('set', () => {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!