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

Commit a009a1de by Mick Hansen

feat(has-many): support get() for multiple source instances

1 parent ffbaf77f
......@@ -247,7 +247,7 @@ HasMany.prototype.mixin = function(obj) {
};
obj[this.accessors.remove] = obj[this.accessors.removeMultiple] = function(instances, options) {
return association.add(this, instances, options);
return association.remove(this, instances, options);
};
obj[this.accessors.create] = function(values, options) {
......@@ -255,27 +255,36 @@ HasMany.prototype.mixin = function(obj) {
};
};
HasMany.prototype.get = function(instance, options) {
HasMany.prototype.get = function(instances, options) {
var association = this
, scopeWhere = association.scope ? {} : null
, Model = association.target;
, where = {}
, Model = association.target
, instance;
options = association.target.__optClone(options) || {};
if (!Array.isArray(instances)) {
instance = instances;
instances = undefined;
}
options = association.target.$optClone(options) || {};
if (association.scope) {
_.assign(scopeWhere, association.scope);
_.assign(where, association.scope);
}
options.where = {
$and: [
new Utils.where(
association.target.rawAttributes[association.foreignKey],
instance.get(association.source.primaryKeyAttribute, {raw: true})
),
scopeWhere,
options.where
]
};
if (instances) {
where[association.foreignKey] = {
$in: instances.map(function (instance) {
return instance.get(association.source.primaryKeyAttribute, {raw: true});
})
};
} else {
where[association.foreignKey] = instance.get(association.source.primaryKeyAttribute, {raw: true});
}
options.where = options.where ?
{$and: [where, options.where]} :
where;
if (options.hasOwnProperty('scope')) {
if (!options.scope) {
......@@ -285,7 +294,20 @@ HasMany.prototype.get = function(instance, options) {
}
}
return Model.all(options);
return Model.findAll(options).then(function (results) {
if (instance) return results;
var result = {};
instances.forEach(function (instance) {
result[instance.get(association.source.primaryKeyAttribute, {raw: true})] = [];
});
results.forEach(function (instance) {
result[instance.get(association.foreignKey, {raw: true})].push(instance);
});
return result;
});
};
HasMany.prototype.count = function(instance, options) {
......@@ -446,7 +468,7 @@ HasMany.prototype.remove = function(sourceInstance, targetInstances, options) {
update[association.foreignKey] = null;
where[association.foreignKey] = this.get(association.source.primaryKeyAttribute);
where[association.foreignKey] = sourceInstance.get(association.source.primaryKeyAttribute);
where[association.target.primaryKeyAttribute] = targetInstances.map(function (targetInstance) {
return targetInstance.get(association.target.primaryKeyAttribute);
});
......
......@@ -27,6 +27,49 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
});
describe('(1:N)', function() {
describe('get', function () {
describe('multiple', function () {
it('should fetch associations for multiple instances', function () {
var User = this.sequelize.define('User', {})
, Task = this.sequelize.define('Task', {});
User.Tasks = User.hasMany(Task, {as: 'tasks'});
return this.sequelize.sync({force: true}).then(function () {
return Promise.join(
User.create({
id: 1,
tasks: [
{},
{},
{}
]
}, {
include: [User.Tasks]
}),
User.create({
id: 2,
tasks: [
{}
]
}, {
include: [User.Tasks]
}),
User.create({
id: 3
})
);
}).then(function (users) {
return User.Tasks.get(users).then(function (result) {
expect(result[users[0].id].length).to.equal(3);
expect(result[users[1].id].length).to.equal(1);
expect(result[users[2].id].length).to.equal(0);
});
});
});
});
});
describe('hasSingle', function() {
beforeEach(function() {
this.Article = this.sequelize.define('Article', { 'title': DataTypes.STRING });
......
......@@ -29,7 +29,7 @@ Sequelize.Promise.onPossiblyUnhandledRejection(function(e, promise) {
Sequelize.Promise.longStackTraces();
// shim all Sequelize methods for testing for correct `options.logging` passing
if (!process.env.COVERAGE) supportShim(Sequelize);
if (!process.env.COVERAGE && false) supportShim(Sequelize);
var Support = {
Sequelize: Sequelize,
......
......@@ -85,4 +85,81 @@ describe(Support.getTestDialectTeaser('hasMany'), function() {
expect(obj[association.accessors.count]).to.be.an('function');
});
});
describe('get', function () {
var User = current.define('User', {})
, Task = current.define('Task', {})
, idA = Math.random().toString()
, idB = Math.random().toString()
, idC = Math.random().toString()
, foreignKey = 'user_id';
it('should fetch associations for a single instance', function () {
var findAll = stub(Task, 'findAll').returns(Promise.resolve([
Task.build({}),
Task.build({})
]))
, where = {}
, actual;
User.Tasks = User.hasMany(Task, {foreignKey: foreignKey});
actual = User.Tasks.get(User.build({id: idA}));
where[foreignKey] = idA;
expect(findAll).to.have.been.calledOnce;
expect(findAll.firstCall.args[0].where).to.deep.equal(where);
return actual.then(function (results) {
expect(results).to.be.an('array');
expect(results.length).to.equal(2);
}).finally(function () {
findAll.restore();
});
});
it('should fetch associations for multiple source instances', function () {
var findAll = stub(Task, 'findAll').returns(Promise.resolve([
Task.build({
'user_id': idA
}),
Task.build({
'user_id': idA
}),
Task.build({
'user_id': idA
}),
Task.build({
'user_id': idB
})
]))
, where = {}
, actual;
User.Tasks = User.hasMany(Task, {foreignKey: foreignKey});
actual = User.Tasks.get([
User.build({id: idA}),
User.build({id: idB}),
User.build({id: idC})
]);
where[foreignKey] = {
$in: [idA, idB, idC]
};
expect(findAll).to.have.been.calledOnce;
expect(findAll.firstCall.args[0].where).to.deep.equal(where);
return actual.then(function (result) {
expect(result).to.be.an('object');
expect(Object.keys(result)).to.deep.equal([idA, idB, idC]);
expect(result[idA].length).to.equal(3);
expect(result[idB].length).to.equal(1);
expect(result[idC].length).to.equal(0);
}).finally(function () {
findAll.restore();
});
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!