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

Commit a7154366 by Mick Hansen

feat(belongs-to-many): countAssociations

1 parent d3ef9e7d
...@@ -272,7 +272,17 @@ var BelongsToMany = function(source, target, options) { ...@@ -272,7 +272,17 @@ var BelongsToMany = function(source, target, options) {
* @return {Promise} * @return {Promise}
* @method hasAssociations * @method hasAssociations
*/ */
hasAll: 'has' + plural hasAll: 'has' + plural,
/**
* Count everything currently associated with this, using an optional where clause
*
* @param {Object} [options]
* @param {Object} [options.where] An optional where clause to limit the associated models
* @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false
* @return {Promise<Array<Instance>>}
* @method countAssociations
*/
count: 'count' + plural
}; };
if (this.options.counterCache) { if (this.options.counterCache) {
...@@ -393,10 +403,8 @@ BelongsToMany.prototype.injectGetter = function(obj) { ...@@ -393,10 +403,8 @@ BelongsToMany.prototype.injectGetter = function(obj) {
throughWhere = {}; throughWhere = {};
throughWhere[association.identifier] = instance.get(association.source.primaryKeyAttribute); throughWhere[association.identifier] = instance.get(association.source.primaryKeyAttribute);
if (through && through.scope) { if (through.scope) {
Object.keys(through.scope).forEach(function (attribute) { _.assign(throughWhere, through.scope);
throughWhere[attribute] = through.scope[attribute];
}.bind(this));
} }
options.include = options.include || []; options.include = options.include || [];
...@@ -429,6 +437,23 @@ BelongsToMany.prototype.injectGetter = function(obj) { ...@@ -429,6 +437,23 @@ BelongsToMany.prototype.injectGetter = function(obj) {
return model.findAll(options); return model.findAll(options);
}; };
obj[this.accessors.count] = function(options) {
var model = association.target
, sequelize = model.sequelize;
options = association.target.__optClone(options) || {};
options.attributes = [
[sequelize.fn('COUNT', sequelize.col(model.primaryKeyAttribute)), 'count']
];
options.joinTableAttributes = [];
options.raw = true;
options.plain = true;
return obj[association.accessors.get].call(this, options).then(function (result) {
return parseInt(result.count, 10);
});
};
obj[this.accessors.hasSingle] = obj[this.accessors.hasAll] = function(instances, options) { obj[this.accessors.hasSingle] = obj[this.accessors.hasAll] = function(instances, options) {
var where = {}; var where = {};
......
...@@ -31,6 +31,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { ...@@ -31,6 +31,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
]); ]);
}).spread(function(john, task1, task2) { }).spread(function(john, task1, task2) {
self.tasks = [task1, task2]; self.tasks = [task1, task2];
self.user = john;
return john.setTasks([task1, task2]); return john.setTasks([task1, task2]);
}); });
}); });
...@@ -410,6 +411,54 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { ...@@ -410,6 +411,54 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
}); });
}); });
describe('countAssociations', function() {
beforeEach(function() {
var self = this;
this.User = this.sequelize.define('User', { username: DataTypes.STRING });
this.Task = this.sequelize.define('Task', { title: DataTypes.STRING, active: DataTypes.BOOLEAN });
this.User.belongsToMany(this.Task, { through: 'UserTasks' });
this.Task.belongsToMany(this.User, { through: 'UserTasks' });
return this.sequelize.sync({ force: true }).then(function() {
return Promise.all([
self.User.create({ username: 'John'}),
self.Task.create({ title: 'Get rich', active: true}),
self.Task.create({ title: 'Die trying', active: false})
]);
}).spread(function(john, task1, task2) {
self.tasks = [task1, task2];
self.user = john;
return john.setTasks([task1, task2]);
});
});
it('should count all associations', function () {
return expect(this.user.countTasks({})).to.eventually.equal(2);
});
it('should count filtered associations', function () {
return expect(this.user.countTasks({
where: {
active: true
}
})).to.eventually.equal(1);
});
it('should count scoped associations', function () {
this.User.belongsToMany(this.Task, {
as: 'activeTasks',
through: 'UserTasks',
scope: {
active: true
}
});
return expect(this.user.countActiveTasks({})).to.eventually.equal(1);
});
});
describe('setAssociations', function() { describe('setAssociations', function() {
it('clears associations when passing null to the set-method', function() { it('clears associations when passing null to the set-method', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING }) var User = this.sequelize.define('User', { username: DataTypes.STRING })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!