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

Commit 9a95e727 by Sushant Committed by GitHub

feat(belongs-to-many): get/has/count for paranoid join table (#12256)

1 parent b49a24d4
...@@ -412,6 +412,7 @@ class BelongsToMany extends Association { ...@@ -412,6 +412,7 @@ class BelongsToMany extends Association {
* @param {string|boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false * @param {string|boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false
* @param {string} [options.schema] Apply a schema on the related model * @param {string} [options.schema] Apply a schema on the related model
* @param {object} [options.through.where] An optional where clause applied to through model (join table) * @param {object} [options.through.where] An optional where clause applied to through model (join table)
* @param {boolean} [options.through.paranoid=true] If true, only non-deleted records will be returned from the join table. If false, both deleted and non-deleted records will be returned. Only applies if through model is paranoid
* *
* @returns {Promise<Array<Model>>} * @returns {Promise<Array<Model>>}
*/ */
...@@ -453,6 +454,7 @@ class BelongsToMany extends Association { ...@@ -453,6 +454,7 @@ class BelongsToMany extends Association {
association: this.oneFromTarget, association: this.oneFromTarget,
attributes: options.joinTableAttributes, attributes: options.joinTableAttributes,
required: true, required: true,
paranoid: _.get(options.through, 'paranoid', true),
where: throughWhere where: throughWhere
}); });
} }
......
...@@ -2446,21 +2446,99 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -2446,21 +2446,99 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
}); });
describe('through', () => { describe('through', () => {
beforeEach(function() { describe('paranoid', () => {
this.User = this.sequelize.define('User', {}); beforeEach(async function() {
this.Project = this.sequelize.define('Project', {}); this.User = this.sequelize.define('User', {});
this.UserProjects = this.sequelize.define('UserProjects', { this.Project = this.sequelize.define('Project', {});
status: DataTypes.STRING, this.UserProjects = this.sequelize.define('UserProjects', {}, {
data: DataTypes.INTEGER paranoid: true
});
this.User.belongsToMany(this.Project, { through: this.UserProjects });
this.Project.belongsToMany(this.User, { through: this.UserProjects });
await this.sequelize.sync();
this.users = await Promise.all([
this.User.create(),
this.User.create(),
this.User.create()
]);
this.projects = await Promise.all([
this.Project.create(),
this.Project.create(),
this.Project.create()
]);
});
it('gets only non-deleted records by default', async function() {
await this.users[0].addProjects(this.projects);
await this.UserProjects.destroy({
where: {
ProjectId: this.projects[0].id
}
});
const result = await this.users[0].getProjects();
expect(result.length).to.equal(2);
}); });
this.User.belongsToMany(this.Project, { through: this.UserProjects }); it('returns both deleted and non-deleted records with paranoid=false', async function() {
this.Project.belongsToMany(this.User, { through: this.UserProjects }); await this.users[0].addProjects(this.projects);
await this.UserProjects.destroy({
where: {
ProjectId: this.projects[0].id
}
});
const result = await this.users[0].getProjects({ through: { paranoid: false } });
expect(result.length).to.equal(3);
});
return this.sequelize.sync(); it('hasAssociation also respects paranoid option', async function() {
await this.users[0].addProjects(this.projects);
await this.UserProjects.destroy({
where: {
ProjectId: this.projects[0].id
}
});
expect(
await this.users[0].hasProjects(this.projects[0], { through: { paranoid: false } })
).to.equal(true);
expect(
await this.users[0].hasProjects(this.projects[0])
).to.equal(false);
expect(
await this.users[0].hasProjects(this.projects[1])
).to.equal(true);
expect(
await this.users[0].hasProjects(this.projects)
).to.equal(false);
});
}); });
describe('fetching from join table', () => { describe('fetching from join table', () => {
beforeEach(function() {
this.User = this.sequelize.define('User', {});
this.Project = this.sequelize.define('Project', {});
this.UserProjects = this.sequelize.define('UserProjects', {
status: DataTypes.STRING,
data: DataTypes.INTEGER
});
this.User.belongsToMany(this.Project, { through: this.UserProjects });
this.Project.belongsToMany(this.User, { through: this.UserProjects });
return this.sequelize.sync();
});
it('should contain the data from the join table on .UserProjects a DAO', async function() { it('should contain the data from the join table on .UserProjects a DAO', async function() {
const [user0, project0] = await Promise.all([ const [user0, project0] = await Promise.all([
this.User.create(), this.User.create(),
...@@ -2523,6 +2601,20 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { ...@@ -2523,6 +2601,20 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => {
}); });
describe('inserting in join table', () => { describe('inserting in join table', () => {
beforeEach(function() {
this.User = this.sequelize.define('User', {});
this.Project = this.sequelize.define('Project', {});
this.UserProjects = this.sequelize.define('UserProjects', {
status: DataTypes.STRING,
data: DataTypes.INTEGER
});
this.User.belongsToMany(this.Project, { through: this.UserProjects });
this.Project.belongsToMany(this.User, { through: this.UserProjects });
return this.sequelize.sync();
});
describe('add', () => { describe('add', () => {
it('should insert data provided on the object into the join table', async function() { it('should insert data provided on the object into the join table', async function() {
const [u, p] = await Promise.all([ const [u, p] = await Promise.all([
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!