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

Commit 8347de69 by Sascha Depold

added self association

1 parent 300f8263
......@@ -36,7 +36,7 @@ HasManyDoubleLinked.prototype.destroyObsoleteAssociations = function(oldAssociat
var emitter = new Utils.CustomEventEmitter(function() {
var chainer = new Utils.QueryChainer
var foreignIdentifier = self.definition.target.associations[self.definition.source.tableName].identifier
var foreignIdentifier = self.definition.target.associations[self.definition.combinedName].identifier
var obsoleteAssociations = oldAssociations.filter(function(obj) { return !obj.equalsOneOf(newAssociations) })
if(obsoleteAssociations.length == 0)
......@@ -73,8 +73,9 @@ HasManyDoubleLinked.prototype.injectSetter = function(emitter, oldAssociations,
.on('failure', function(err) { emitter.emit('failure', err) })
.on('success', function() {
var chainer = new Utils.QueryChainer
var foreignIdentifier = self.definition.target.associations[self.definition.source.tableName].identifier
var unassociatedObjects = newAssociations.filter(function(obj) { return !obj.equalsOneOf(oldAssociations) })
, association = self.definition.target.associations[self.definition.combinedName]
, foreignIdentifier = association.isSelfAssociation ? association.foreignIdentifier : association.identifier
, unassociatedObjects = newAssociations.filter(function(obj) { return !obj.equalsOneOf(oldAssociations) })
unassociatedObjects.forEach(function(unassociatedObject) {
var attributes = {}
......
......@@ -8,6 +8,12 @@ var HasMany = module.exports = function(srcModel, targetModel, options) {
this.source = srcModel
this.target = targetModel
this.options = options
this.isSelfAssociation = (this.source.tableName == this.target.tableName)
this.combinedName = Utils.combineTableNames(
this.source.tableName,
this.isSelfAssociation ? (this.options.as || this.target.tableName) : this.target.tableName
)
var as = (this.options.as || Utils.pluralize(this.target.tableName))
......@@ -22,21 +28,27 @@ var HasMany = module.exports = function(srcModel, targetModel, options) {
// the id is in the target table
// or in an extra table which connects two tables
HasMany.prototype.injectAttributes = function() {
var multiAssociation = this.target.associations.hasOwnProperty(this.combinedName)
this.identifier = this.options.foreignKey || Utils._.underscoredIf(Utils.singularize(this.source.tableName) + "Id", this.options.underscored)
if (this.target.associations.hasOwnProperty(this.source.tableName)) {
// is there already a single sided association between the source and the target?
// or is the association on the model itself?
if (this.isSelfAssociation || multiAssociation) {
// remove the obsolete association identifier from the source
this.foreignIdentifier = this.target.associations[this.source.tableName].identifier
if(this.isSelfAssociation) {
this.foreignIdentifier = (this.options.as || this.target.tableName) + 'Id'
} else {
this.foreignIdentifier = this.target.associations[this.combinedName].identifier
delete this.source.attributes[this.foreignIdentifier]
}
// define a new model, which connects the models
var combinedTableAttributes = {}
combinedTableAttributes[this.identifier] = {type:DataTypes.INTEGER, primaryKey: true}
combinedTableAttributes[this.foreignIdentifier] = {type:DataTypes.INTEGER, primaryKey: true}
this.connectorModel =
this.target.associations[this.source.tableName].connectorModel =
this.source.modelManager.sequelize.define(Utils.combineTableNames(this.source.tableName, this.target.tableName), combinedTableAttributes)
this.connectorModel = this.source.modelManager.sequelize.define( this.combinedName, combinedTableAttributes )
if(!this.isSelfAssociation) this.target.associations[this.combinedName].connectorModel = this.connectorModel
this.connectorModel.sync()
} else {
......
......@@ -21,7 +21,7 @@ var Associations = module.exports = {
// the id is in the foreign table or in a connecting table
var HasMany = require("./has-many")
var association = new HasMany(this, associatedModel, Utils._.extend((options||{}), this.options))
this.associations[associatedModel.tableName] = association.injectAttributes()
this.associations[association.combinedName] = association.injectAttributes()
}
},
instanceMethods: {
......
......@@ -140,7 +140,6 @@ ModelDefinition.prototype.build = function(values, options) {
}
})
Utils._.each(this.options.instanceMethods || {}, function(fct, name) { instance[name] = fct })
Utils._.each(this.associations, function(association, associationName) {
association.injectGetter(instance)
association.injectSetter(instance)
......
......@@ -196,5 +196,46 @@ module.exports = {
})
})
})
},
'it should correctly build the connector model names': function(exit){
var num = parseInt(Math.random() * 99999999)
, Person = sequelize.define('Person' + num, { name: Sequelize.STRING })
Person.hasMany(Person, {as: 'Children'})
Person.hasMany(Person, {as: 'Friends'})
Person.hasMany(Person, {as: 'CoWorkers'})
Person.sync({force: true}).on('success', function() {
var modelNames = sequelize.modelManager.models.map(function(model) { return model.tableName })
, expectation = ["Person" + num + "s", "ChildrenPerson" + num + "s", "CoWorkersPerson" + num + "s", "FriendsPerson" + num + "s"]
expectation.forEach(function(ex) {
assert.eql(modelNames.indexOf(ex) > -1, true)
})
exit(function(){})
})
},
'it should correctly get and set the connected models': function(exit) {
var num = parseInt(Math.random() * 99999999)
, Person = sequelize.define('Person' + num, { name: Sequelize.STRING })
Person.hasMany(Person, {as: 'Children'})
Person.hasMany(Person, {as: 'Friends'})
Person.hasMany(Person, {as: 'CoWorkers'})
Person.sync({force: true}).on('success', function() {
Person.create({name: 'foobar'}).on('success', function(person) {
Person.create({name: 'friend'}).on('success', function(friend) {
person.setFriends([friend]).on('success', function() {
person.getFriends().on('success', function(friends) {
assert.eql(friends.length, 1)
assert.eql(friends[0].name, 'friend')
exit(function(){})
})
})
})
})
})
}
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!