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

Commit 1ce11279 by Mick Hansen

Merge pull request #2560 from simong/remove-multiple

#2338 - Associations remove[AS][plural]
2 parents ffc50e13 c9675356
# Next
- [FEATURE] Added the possibility of removing multiple associations in 1 call [#2338](https://github.com/sequelize/sequelize/issues/2338)
- [BUG] Add support for `field` named the same as the attribute in `reload`, `bulkCreate` and `save` [#2348](https://github.com/sequelize/sequelize/issues/2348)
- [BUG] Copy the options object in association getters. [#2311](https://github.com/sequelize/sequelize/issues/2311)
- [BUG] `Model#destroy()` now supports `field`, this also fixes an issue with `N:M#removeAssociation` and `field`
......
......@@ -176,6 +176,7 @@ module.exports = (function() {
add: 'add' + singular,
create: 'create' + singular,
remove: 'remove' + singular,
removeMultiple: 'remove' + plural,
hasSingle: 'has' + singular,
hasAll: 'has' + plural
};
......@@ -483,6 +484,29 @@ module.exports = (function() {
});
};
obj[this.accessors.removeMultiple] = function(oldAssociatedObjects, options) {
var instance = this;
return instance[association.accessors.get]({}, options).then(function(currentAssociatedObjects) {
var newAssociations = [];
currentAssociatedObjects.forEach(function(association) {
// Determine is this is an association we want to remove
var obj = Utils._.find(oldAssociatedObjects, function(oldAssociatedObject) {
return Utils._.isEqual(oldAssociatedObject.identifiers, association.identifiers);
});
// This is not an association we want to remove. Add it back
// to the set of associations we will associate our instance with
if (!obj) {
newAssociations.push(association);
}
});
return instance[association.accessors.set](newAssociations, options);
});
};
return this;
};
......
......@@ -187,7 +187,8 @@ Mixin.belongsTo = singleLinked(BelongsTo);
* * add[AS] - for example addPicture(instance, defaultAttributes|options). Add another associated object.
* * add[AS] [plural] - for example addPictures([instance1, instance2], defaultAttributes|options). Add some more associated objects.
* * create[AS] - for example createPicture(values, options). Build and save a new association.
* * remove[AS] - for example removePicture(instance). Remove a single association
* * remove[AS] - for example removePicture(instance). Remove a single association.
* * remove[AS] [plural] - for example removePictures(instance). Remove multiple association.
* * has[AS] - for example hasPicture(instance). Is source associated to this target?
* * has[AS] [plural] - for example hasPictures(instances). Is source associated to all these targets?
*
......
......@@ -1986,6 +1986,34 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
expect(tasks.length).to.equal(1);
});
});
it('should remove multiple entries without any attributes (and timestamps off) on the through model', function () {
var Worker = this.sequelize.define('Worker', {}, {timestamps: false})
, Task = this.sequelize.define('Task', {}, {timestamps: false})
, WorkerTasks = this.sequelize.define('WorkerTasks', {}, {timestamps: false});
Worker.hasMany(Task, { through: WorkerTasks });
Task.hasMany(Worker, { through: WorkerTasks });
// Test setup
return this.sequelize.sync().then(function() {
return Sequelize.Promise.all([
Worker.create({}),
Task.bulkCreate([{}, {}, {}]).then(function () {
return Task.findAll();
})
]);
}).spread(function (worker, tasks) {
// Set all tasks, then remove two tasks, then return all tasks
return worker.setTasks(tasks).then(function () {
return worker.removeTasks([tasks[0], tasks[1]]);
}).then(function () {
return worker.getTasks();
});
}).then(function (tasks) {
expect(tasks.length).to.equal(1);
});
});
});
});
......
......@@ -137,7 +137,12 @@ if (Support.dialectIsMySQL()) {
self.user.removeTask(self.tasks[0]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
expect(_tasks.length).to.equal(self.tasks.length - 1)
done()
self.user.removeTasks([self.tasks[1], self.tasks[2]]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length - 3)
done()
})
})
})
})
})
......
......@@ -151,7 +151,12 @@ if (dialect.match(/^postgres/)) {
self.user.removeTask(self.tasks[0]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length - 1)
done()
self.user.removeTasks([self.tasks[1], self.tasks[2]]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length - 3)
done()
})
})
})
})
})
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!