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

Commit 09ac0969 by Mick Hansen

Merge pull request #1194 from mickhansen/has-many-through-self-association-fix

Add test and fix for hasMany selfAssociation with through option (Fixes #1184)
2 parents 9a219699 033e0939
......@@ -56,9 +56,16 @@ module.exports = (function() {
}
/*
* Find partner DAOFactory if present, to identify double linked association
* If self association, this association is target association
*/
if (this.through) {
if (this.isSelfAssociation) {
this.targetAssociation = this
}
/*
* Else find partner DAOFactory if present, to identify double linked association
*/
else if (this.through) {
_.each(this.target.associations, function (association, accessor) {
if (self.source === association.target) {
var paired = false
......@@ -90,13 +97,14 @@ module.exports = (function() {
if (this.through === true) {
this.through = this.combinedTableName
}
}
if (typeof this.through === "string") {
this.through = this.sequelize.define(this.through, {}, _.extend(this.options, {
tableName: this.through
}))
this.targetAssociation.through = this.through
}
if (this.targetAssociation) this.targetAssociation.through = this.through
}
this.options.tableName = this.combinedName = (this.through === Object(this.through) ? this.through.tableName : this.through)
......@@ -238,7 +246,7 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) {
instance[self.accessors.get]()
.success(function(oldAssociatedObjects) {
var Class = self.doubleLinked ? HasManyMultiLinked : HasManySingleLinked
var Class = Object(self.through) === self.through ? HasManyMultiLinked : HasManySingleLinked
new Class(self, instance).injectSetter(emitter, oldAssociatedObjects, newAssociatedObjects, defaultAttributes)
})
.proxy(emitter, {events: ['error', 'sql']})
......@@ -258,7 +266,7 @@ module.exports = (function() {
.proxy(emitter, {events: ['error', 'sql']})
.success(function(currentAssociatedObjects) {
if (currentAssociatedObjects.length === 0 || Object(self.through) === self.through) {
var Class = self.doubleLinked ? HasManyMultiLinked : HasManySingleLinked
var Class = Object(self.through) === self.through ? HasManyMultiLinked : HasManySingleLinked
new Class(self, instance).injectAdder(emitter, newAssociatedObject, additionalAttributes, !!currentAssociatedObjects.length)
} else {
emitter.emit('success', newAssociatedObject);
......
......@@ -399,7 +399,7 @@ module.exports = (function() {
optAttributes = optAttributes.concat(attributes)
if (include.association.doubleLinked) {
if (Object(include.association.through) === include.association.through) {
var primaryKeysSource = Object.keys(include.association.source.primaryKeys)
, tableSource = parentTable
, identSource = include.association.identifier
......
......@@ -429,6 +429,19 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
})
})
}) // end optimization using bulk create, destroy and update
describe('selfAssociations', function () {
it('should work', function (done) {
var Group = this.sequelize.define('Group', {})
Group.hasMany(Group, { through: 'groups_outsourcing_companies', as: 'OutsourcingCompanies'});
this.sequelize.sync().done(function (err) {
expect(err).not.to.be.ok
done()
})
})
})
})
describe('(N:M)', function() {
......
......@@ -478,6 +478,40 @@ describe(Support.getTestDialectTeaser("Include"), function () {
})
})
})
it('should support self associated hasMany (with through) include', function (done) {
var Group = this.sequelize.define('Group', {
name: DataTypes.STRING
})
Group.hasMany(Group, { through: 'groups_outsourcing_companies', as: 'OutsourcingCompanies'});
this.sequelize.sync().done(function (err) {
Group.bulkCreate([
{name: 'SoccerMoms'},
{name: 'Coca Cola'},
{name: 'Dell'},
{name: 'Pepsi'}
]).done(function () {
Group.findAll().done(function (err, groups) {
groups[0].setOutsourcingCompanies(groups.slice(1)).done(function (err) {
expect(err).not.to.be.ok
Group.find({
where: {
id: groups[0].id,
},
include: [{model: Group, as: 'OutsourcingCompanies'}]
}).done(function (err, group) {
expect(err).not.to.be.ok
expect(group.outsourcingCompanies.length).to.equal(3)
done()
})
})
})
})
})
})
})
describe('findAll', function () {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!