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

Commit 12700ca0 by Andrew Heuermann Committed by Sushant

fix(associations): gets on many-to-many with non-primary target key (#11778)

1 parent ba9a2f65
...@@ -355,6 +355,7 @@ class BelongsToMany extends Association { ...@@ -355,6 +355,7 @@ class BelongsToMany extends Association {
}); });
this.oneFromSource = new HasOne(this.source, this.through.model, { this.oneFromSource = new HasOne(this.source, this.through.model, {
foreignKey: this.foreignKey, foreignKey: this.foreignKey,
sourceKey: this.sourceKey,
as: this.through.model.name as: this.through.model.name
}); });
...@@ -366,6 +367,7 @@ class BelongsToMany extends Association { ...@@ -366,6 +367,7 @@ class BelongsToMany extends Association {
}); });
this.oneFromTarget = new HasOne(this.target, this.through.model, { this.oneFromTarget = new HasOne(this.target, this.through.model, {
foreignKey: this.otherKey, foreignKey: this.otherKey,
sourceKey: this.targetKey,
as: this.through.model.name as: this.through.model.name
}); });
...@@ -376,6 +378,7 @@ class BelongsToMany extends Association { ...@@ -376,6 +378,7 @@ class BelongsToMany extends Association {
this.paired.oneFromTarget = new HasOne(this.paired.target, this.paired.through.model, { this.paired.oneFromTarget = new HasOne(this.paired.target, this.paired.through.model, {
foreignKey: this.paired.otherKey, foreignKey: this.paired.otherKey,
sourceKey: this.paired.targetKey,
as: this.paired.through.model.name as: this.paired.through.model.name
}); });
} }
......
...@@ -731,6 +731,85 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -731,6 +731,85 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
}); });
}); });
it('supports non primary key attributes for joins for getting associations (sourceKey/targetKey)', function() {
const User = this.sequelize.define('User', {
userId: {
type: DataTypes.UUID,
allowNull: false,
primaryKey: true,
defaultValue: DataTypes.UUIDV4
},
userSecondId: {
type: DataTypes.UUID,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
field: 'user_second_id'
}
}, {
tableName: 'tbl_user',
indexes: [
{
unique: true,
fields: ['user_second_id']
}
]
});
const Group = this.sequelize.define('Group', {
groupId: {
type: DataTypes.UUID,
allowNull: false,
primaryKey: true,
defaultValue: DataTypes.UUIDV4
},
groupSecondId: {
type: DataTypes.UUID,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
field: 'group_second_id'
}
}, {
tableName: 'tbl_group',
indexes: [
{
unique: true,
fields: ['group_second_id']
}
]
});
User.belongsToMany(Group, { through: 'usergroups', sourceKey: 'userSecondId', targetKey: 'groupSecondId' });
Group.belongsToMany(User, { through: 'usergroups', sourceKey: 'groupSecondId', targetKey: 'userSecondId' });
return this.sequelize.sync({ force: true }).then(() => {
return Promise.join(
User.create(),
User.create(),
Group.create(),
Group.create()
).then(([user1, user2, group1, group2]) => {
return Promise.join(user1.addGroup(group1), user2.addGroup(group2))
.then(() => {
return Promise.join(
user1.getGroups(),
user2.getGroups(),
group1.getUsers(),
group2.getUsers()
);
}).then(([groups1, groups2, users1, users2]) => {
expect(groups1.length).to.be.equal(1);
expect(groups1[0].id).to.be.equal(group1.id);
expect(groups2.length).to.be.equal(1);
expect(groups2[0].id).to.be.equal(group2.id);
expect(users1.length).to.be.equal(1);
expect(users1[0].id).to.be.equal(user1.id);
expect(users2.length).to.be.equal(1);
expect(users2[0].id).to.be.equal(user2.id);
});
});
});
});
it('supports non primary key attributes for joins (custom foreignKey)', function() { it('supports non primary key attributes for joins (custom foreignKey)', function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
id: { id: {
......
...@@ -332,7 +332,7 @@ describe(Support.getTestDialectTeaser('belongsToMany'), () => { ...@@ -332,7 +332,7 @@ describe(Support.getTestDialectTeaser('belongsToMany'), () => {
expect(Object.keys(ProductTag.rawAttributes)).to.deep.equal(['id', 'priority', 'productId', 'tagId']); expect(Object.keys(ProductTag.rawAttributes)).to.deep.equal(['id', 'priority', 'productId', 'tagId']);
}); });
it('should setup hasOne relations to source and target from join model with defined foreign/other keys', function() { it('should setup hasMany relations to source and target from join model with defined foreign/other keys', function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
}), }),
...@@ -406,6 +406,45 @@ describe(Support.getTestDialectTeaser('belongsToMany'), () => { ...@@ -406,6 +406,45 @@ describe(Support.getTestDialectTeaser('belongsToMany'), () => {
expect(Object.keys(ProductTag.rawAttributes)).to.deep.equal(['id', 'priority', 'productId', 'tagId']); expect(Object.keys(ProductTag.rawAttributes)).to.deep.equal(['id', 'priority', 'productId', 'tagId']);
}); });
it('should setup hasOne relations to source and target from join model with defined source keys', function() {
const Product = this.sequelize.define('Product', {
title: DataTypes.STRING,
productSecondaryId: DataTypes.STRING
}),
Tag = this.sequelize.define('Tag', {
name: DataTypes.STRING,
tagSecondaryId: DataTypes.STRING
}),
ProductTag = this.sequelize.define('ProductTag', {
id: {
primaryKey: true,
type: DataTypes.INTEGER,
autoIncrement: true
},
priority: DataTypes.INTEGER
}, {
timestamps: false
});
Product.Tags = Product.belongsToMany(Tag, { through: ProductTag, sourceKey: 'productSecondaryId' });
Tag.Products = Tag.belongsToMany(Product, { through: ProductTag, sourceKey: 'tagSecondaryId' });
expect(Product.Tags.oneFromSource).to.be.an.instanceOf(HasOne);
expect(Product.Tags.oneFromTarget).to.be.an.instanceOf(HasOne);
expect(Tag.Products.oneFromSource).to.be.an.instanceOf(HasOne);
expect(Tag.Products.oneFromTarget).to.be.an.instanceOf(HasOne);
expect(Tag.Products.oneFromSource.sourceKey).to.equal(Tag.Products.sourceKey);
expect(Tag.Products.oneFromTarget.sourceKey).to.equal(Tag.Products.targetKey);
expect(Product.Tags.oneFromSource.sourceKey).to.equal(Product.Tags.sourceKey);
expect(Product.Tags.oneFromTarget.sourceKey).to.equal(Product.Tags.targetKey);
expect(Object.keys(ProductTag.rawAttributes).length).to.equal(4);
expect(Object.keys(ProductTag.rawAttributes)).to.deep.equal(['id', 'priority', 'ProductProductSecondaryId', 'TagTagSecondaryId']);
});
it('should setup belongsTo relations to source and target from join model with only foreign keys defined', function() { it('should setup belongsTo relations to source and target from join model with only foreign keys defined', function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!