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

Commit 43ab707d by RobertYoung Committed by Sushant

feat(associations): enable overwrite unique constraint key name (#10045)

1 parent 8fe475b6
......@@ -285,6 +285,11 @@ User.findAll({
}]
});
```
Belongs-To-Many creates a unique key when primary key is not present on through model. This unique key name can be overridden using **uniqueKey** option.
```js
Project.belongsToMany(User, { through: UserProjects, uniqueKey: 'my_custom_unique' })
```
## Scopes
This section concerns association scopes. For a definition of association scopes vs. scopes on associated models, see [Scopes](/manual/tutorial/scopes.html).
......
......@@ -259,7 +259,12 @@ class BelongsToMany extends Association {
if (this.primaryKeyDeleted === true) {
targetAttribute.primaryKey = sourceAttribute.primaryKey = true;
} else if (this.through.unique !== false) {
const uniqueKey = [this.through.model.tableName, this.foreignKey, this.otherKey, 'unique'].join('_');
let uniqueKey;
if (typeof this.options.uniqueKey === 'string' && this.options.uniqueKey !== '') {
uniqueKey = this.options.uniqueKey;
} else {
uniqueKey = [this.through.model.tableName, this.foreignKey, this.otherKey, 'unique'].join('_');
}
targetAttribute.unique = sourceAttribute.unique = uniqueKey;
}
......
......@@ -3212,6 +3212,7 @@ class Model {
*/
setDataValue(key, value) {
const originalValue = this._previousDataValues[key];
if (!Utils.isPrimitive(value) || value !== originalValue) {
this.changed(key, true);
}
......@@ -4177,6 +4178,7 @@ class Model {
* @param {string} [options.onDelete='SET NULL|CASCADE'] SET NULL if foreignKey allows nulls, CASCADE if otherwise
* @param {string} [options.onUpdate='CASCADE']
* @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key.
* @param {string} [options.uniqueKey] The custom name for unique constraint.
* @returns {HasOne}
* @example
* User.hasOne(Profile) // This will add userId to the profile table
......
......@@ -2157,6 +2157,35 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
expect(ut2).to.have.length(1);
});
});
it('create custom unique identifier', function() {
this.UserTasksLong = this.sequelize.define('table_user_task_with_very_long_name', {
id_user_very_long_field: {
type: DataTypes.INTEGER(1)
},
id_task_very_long_field: {
type: DataTypes.INTEGER(1)
}
},
{ tableName: 'table_user_task_with_very_long_name' }
);
this.User.belongsToMany(this.Task, {
as: 'MyTasks',
through: this.UserTasksLong,
foreignKey: 'id_user_very_long_field'
});
this.Task.belongsToMany(this.User, {
as: 'MyUsers',
through: this.UserTasksLong,
foreignKey: 'id_task_very_long_field',
uniqueKey: 'custom_user_group_unique'
});
return this.sequelize.sync({ force: true }).then(() => {
expect(this.Task.associations.MyUsers.through.model.rawAttributes.id_user_very_long_field.unique).to.equal('custom_user_group_unique');
expect(this.Task.associations.MyUsers.through.model.rawAttributes.id_task_very_long_field.unique).to.equal('custom_user_group_unique');
});
});
});
describe('Association options', () => {
......
......@@ -214,7 +214,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
if (dialect === 'sqlite') {
expect(created).to.be.undefined;
} else {
expect(created).to.be.okay;
expect(created).to.be.ok;
}
});
});
......
......@@ -585,5 +585,67 @@ describe(Support.getTestDialectTeaser('belongsToMany'), () => {
expect(Group.associations.MyUsers.through.model.rawAttributes.GroupId.onUpdate).to.equal('SET NULL');
expect(Group.associations.MyUsers.through.model.rawAttributes.GroupId.onDelete).to.equal('RESTRICT');
});
it('generate unique identifier with very long length', function() {
const User = this.sequelize.define('User', {}, { tableName: 'table_user_with_very_long_name' }),
Group = this.sequelize.define('Group', {}, { tableName: 'table_group_with_very_long_name' }),
UserGroup = this.sequelize.define(
'GroupUser',
{
id_user_very_long_field: {
type: DataTypes.INTEGER(1)
},
id_group_very_long_field: {
type: DataTypes.INTEGER(1)
}
},
{tableName: 'table_user_group_with_very_long_name'}
);
User.belongsToMany(Group, { as: 'MyGroups', through: UserGroup, foreignKey: 'id_user_very_long_field' });
Group.belongsToMany(User, { as: 'MyUsers', through: UserGroup, foreignKey: 'id_group_very_long_field' });
expect(Group.associations.MyUsers.through.model === User.associations.MyGroups.through.model);
expect(Group.associations.MyUsers.through.model.rawAttributes.id_user_very_long_field.unique).to.have.lengthOf(92);
expect(Group.associations.MyUsers.through.model.rawAttributes.id_group_very_long_field.unique).to.have.lengthOf(92);
expect(Group.associations.MyUsers.through.model.rawAttributes.id_user_very_long_field.unique).to.equal('table_user_group_with_very_long_name_id_group_very_long_field_id_user_very_long_field_unique');
expect(Group.associations.MyUsers.through.model.rawAttributes.id_group_very_long_field.unique).to.equal('table_user_group_with_very_long_name_id_group_very_long_field_id_user_very_long_field_unique');
});
it('generate unique identifier with custom name', function() {
const User = this.sequelize.define('User', {}, { tableName: 'table_user_with_very_long_name' }),
Group = this.sequelize.define('Group', {}, { tableName: 'table_group_with_very_long_name' }),
UserGroup = this.sequelize.define(
'GroupUser',
{
id_user_very_long_field: {
type: DataTypes.INTEGER(1)
},
id_group_very_long_field: {
type: DataTypes.INTEGER(1)
}
},
{tableName: 'table_user_group_with_very_long_name'}
);
User.belongsToMany(Group, {
as: 'MyGroups',
through: UserGroup,
foreignKey: 'id_user_very_long_field',
uniqueKey: 'custom_user_group_unique'
});
Group.belongsToMany(User, {
as: 'MyUsers',
through: UserGroup,
foreignKey: 'id_group_very_long_field',
uniqueKey: 'custom_user_group_unique'
});
expect(Group.associations.MyUsers.through.model === User.associations.MyGroups.through.model);
expect(Group.associations.MyUsers.through.model.rawAttributes.id_user_very_long_field.unique).to.have.lengthOf(24);
expect(Group.associations.MyUsers.through.model.rawAttributes.id_group_very_long_field.unique).to.have.lengthOf(24);
expect(Group.associations.MyUsers.through.model.rawAttributes.id_user_very_long_field.unique).to.equal('custom_user_group_unique');
expect(Group.associations.MyUsers.through.model.rawAttributes.id_group_very_long_field.unique).to.equal('custom_user_group_unique');
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!