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

Commit 1bd525d2 by Jan Aagaard Meier

Refactored associations to use promises, and added addRelations

1 parent 9393986b
var Utils = require("./../utils") var Utils = require("./../utils")
, DataTypes = require('./../data-types')
, Helpers = require('./helpers') , Helpers = require('./helpers')
, Transaction = require('../transaction') , Transaction = require('../transaction')
, _ = require('lodash')
module.exports = (function() { module.exports = (function() {
var BelongsTo = function(source, target, options) { var BelongsTo = function(source, target, options) {
......
...@@ -12,16 +12,12 @@ module.exports = (function() { ...@@ -12,16 +12,12 @@ module.exports = (function() {
HasManyDoubleLinked.prototype.injectGetter = function(options) { HasManyDoubleLinked.prototype.injectGetter = function(options) {
var self = this var self = this
, _options = options
, smart
var customEventEmitter = new Utils.CustomEventEmitter(function() {
var where = []
, through = self.association.through , through = self.association.through
, options = _options || {}
, queryOptions = {} , queryOptions = {}
, targetAssociation = self.association.targetAssociation , targetAssociation = self.association.targetAssociation
options = options || {}
//fully qualify //fully qualify
var instancePrimaryKey = self.instance.Model.primaryKeyAttribute var instancePrimaryKey = self.instance.Model.primaryKeyAttribute
, foreignPrimaryKey = self.association.target.primaryKeyAttribute , foreignPrimaryKey = self.association.target.primaryKeyAttribute
...@@ -70,18 +66,11 @@ module.exports = (function() { ...@@ -70,18 +66,11 @@ module.exports = (function() {
} }
} }
self.association.target.findAllJoin([through.getTableName(), through.name], options, queryOptions) return self.association.target.findAllJoin([through.getTableName(), through.name], options, queryOptions)
.on('success', function(objects) { customEventEmitter.emit('success', objects) })
.on('error', function(err){ customEventEmitter.emit('error', err) })
.on('sql', function(sql) { customEventEmitter.emit('sql', sql)})
})
return customEventEmitter.run()
} }
HasManyDoubleLinked.prototype.injectSetter = function(emitterProxy, oldAssociations, newAssociations, defaultAttributes) { HasManyDoubleLinked.prototype.injectSetter = function(oldAssociations, newAssociations, defaultAttributes) {
var self = this var self = this
, chainer = new Utils.QueryChainer()
, targetAssociation = self.association.targetAssociation , targetAssociation = self.association.targetAssociation
, foreignIdentifier = self.association.foreignIdentifier , foreignIdentifier = self.association.foreignIdentifier
, sourceKeys = Object.keys(self.association.source.primaryKeys) , sourceKeys = Object.keys(self.association.source.primaryKeys)
...@@ -89,6 +78,7 @@ module.exports = (function() { ...@@ -89,6 +78,7 @@ module.exports = (function() {
, obsoleteAssociations = [] , obsoleteAssociations = []
, changedAssociations = [] , changedAssociations = []
, options = {} , options = {}
, promises = []
, unassociatedObjects; , unassociatedObjects;
if ((defaultAttributes || {}).transaction instanceof Transaction) { if ((defaultAttributes || {}).transaction instanceof Transaction) {
...@@ -140,7 +130,7 @@ module.exports = (function() { ...@@ -140,7 +130,7 @@ module.exports = (function() {
where[self.association.identifier] = ((sourceKeys.length === 1) ? self.instance[sourceKeys[0]] : self.instance.id) where[self.association.identifier] = ((sourceKeys.length === 1) ? self.instance[sourceKeys[0]] : self.instance.id)
where[foreignIdentifier] = foreignIds where[foreignIdentifier] = foreignIds
chainer.add(self.association.through.destroy(where, options)) promises.push(self.association.through.destroy(where, options))
} }
if (unassociatedObjects.length > 0) { if (unassociatedObjects.length > 0) {
...@@ -157,23 +147,19 @@ module.exports = (function() { ...@@ -157,23 +147,19 @@ module.exports = (function() {
return attributes return attributes
}) })
chainer.add(self.association.through.bulkCreate(bulk, options)) promises.push(self.association.through.bulkCreate(bulk, options))
} }
if (changedAssociations.length > 0) { if (changedAssociations.length > 0) {
changedAssociations.forEach(function (assoc) { changedAssociations.forEach(function (assoc) {
chainer.add(self.association.through.update(assoc.attributes, assoc.where, options)) promises.push(self.association.through.update(assoc.attributes, assoc.where, options))
}) })
} }
chainer return Utils.Promise.all(promises)
.run()
.success(function() { emitterProxy.emit('success', newAssociations) })
.error(function(err) { emitterProxy.emit('error', err) })
.on('sql', function(sql) { emitterProxy.emit('sql', sql) })
} }
HasManyDoubleLinked.prototype.injectAdder = function(emitterProxy, newAssociation, additionalAttributes, exists) { HasManyDoubleLinked.prototype.injectAdder = function(newAssociation, additionalAttributes, exists) {
var attributes = {} var attributes = {}
, targetAssociation = this.association.targetAssociation , targetAssociation = this.association.targetAssociation
, foreignIdentifier = targetAssociation.identifier , foreignIdentifier = targetAssociation.identifier
...@@ -195,17 +181,14 @@ module.exports = (function() { ...@@ -195,17 +181,14 @@ module.exports = (function() {
attributes = Utils._.defaults({}, newAssociation[targetAssociation.through.name], additionalAttributes) attributes = Utils._.defaults({}, newAssociation[targetAssociation.through.name], additionalAttributes)
if (Object.keys(attributes).length) { if (Object.keys(attributes).length) {
targetAssociation.through.update(attributes, where).proxy(emitterProxy) return targetAssociation.through.update(attributes, where)
} else { } else {
emitterProxy.emit('success') return Utils.Promise.resolve()
} }
} else { } else {
attributes = Utils._.defaults(attributes, newAssociation[targetAssociation.through.name], additionalAttributes) attributes = Utils._.defaults(attributes, newAssociation[targetAssociation.through.name], additionalAttributes)
this.association.through.create(attributes, options) return this.association.through.create(attributes, options)
.success(function() { emitterProxy.emit('success', newAssociation) })
.error(function(err) { emitterProxy.emit('error', err) })
.on('sql', function(sql) { emitterProxy.emit('sql', sql) })
} }
} }
......
...@@ -24,12 +24,12 @@ module.exports = (function() { ...@@ -24,12 +24,12 @@ module.exports = (function() {
return this.association.target.all(options) return this.association.target.all(options)
} }
HasManySingleLinked.prototype.injectSetter = function(emitter, oldAssociations, newAssociations, defaultAttributes) { HasManySingleLinked.prototype.injectSetter = function(oldAssociations, newAssociations, defaultAttributes) {
var self = this var self = this
, associationKeys = Object.keys((oldAssociations[0] || newAssociations[0] || {Model: {primaryKeys: {}}}).Model.primaryKeys || {}) , associationKeys = Object.keys((oldAssociations[0] || newAssociations[0] || {Model: {primaryKeys: {}}}).Model.primaryKeys || {})
, associationKey = (associationKeys.length === 1) ? associationKeys[0] : 'id' , associationKey = (associationKeys.length === 1) ? associationKeys[0] : 'id'
, chainer = new Utils.QueryChainer()
, options = {} , options = {}
, promises = []
, obsoleteAssociations = oldAssociations.filter(function (old) { , obsoleteAssociations = oldAssociations.filter(function (old) {
return !Utils._.find(newAssociations, function (obj) { return !Utils._.find(newAssociations, function (obj) {
return obj[associationKey] === old[associationKey] return obj[associationKey] === old[associationKey]
...@@ -62,7 +62,7 @@ module.exports = (function() { ...@@ -62,7 +62,7 @@ module.exports = (function() {
, updateWhere = {} , updateWhere = {}
updateWhere[primaryKey] = obsoleteIds updateWhere[primaryKey] = obsoleteIds
chainer.add(this.__factory.target.update( promises.push(this.__factory.target.update(
update, update,
updateWhere, updateWhere,
Utils._.extend(options, { allowNull: [self.__factory.identifier] }) Utils._.extend(options, { allowNull: [self.__factory.identifier] })
...@@ -88,21 +88,17 @@ module.exports = (function() { ...@@ -88,21 +88,17 @@ module.exports = (function() {
update[self.__factory.identifier] = (newAssociations.length < 1 ? null : self.instance[pkey] || self.instance.id) update[self.__factory.identifier] = (newAssociations.length < 1 ? null : self.instance[pkey] || self.instance.id)
updateWhere[primaryKey] = unassociatedIds updateWhere[primaryKey] = unassociatedIds
chainer.add(this.__factory.target.update( promises.push(this.__factory.target.update(
update, update,
updateWhere, updateWhere,
Utils._.extend(options, { allowNull: [self.__factory.identifier] }) Utils._.extend(options, { allowNull: [self.__factory.identifier] })
)) ))
} }
chainer return Utils.Promise.all(promises)
.run()
.success(function() { emitter.emit('success', newAssociations) })
.error(function(err) { emitter.emit('error', err) })
.on('sql', function(sql) { emitter.emit('sql', sql) })
} }
HasManySingleLinked.prototype.injectAdder = function(emitterProxy, newAssociation, additionalAttributes) { HasManySingleLinked.prototype.injectAdder = function(newAssociation, additionalAttributes) {
var primaryKeys = Object.keys(this.instance.Model.primaryKeys) var primaryKeys = Object.keys(this.instance.Model.primaryKeys)
, primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id' , primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id'
, options = {} , options = {}
...@@ -114,10 +110,7 @@ module.exports = (function() { ...@@ -114,10 +110,7 @@ module.exports = (function() {
newAssociation[this.__factory.identifier] = this.instance[primaryKey] newAssociation[this.__factory.identifier] = this.instance[primaryKey]
newAssociation.save(options) return newAssociation.save(options)
.success(function() { emitterProxy.emit('success', newAssociation) })
.error(function(err) { emitterProxy.emit('error', err) })
.on('sql', function(sql) { emitterProxy.emit('sql', sql) })
} }
return HasManySingleLinked return HasManySingleLinked
......
var Utils = require("./../utils") var Utils = require("./../utils")
, DataTypes = require('./../data-types')
, Helpers = require('./helpers') , Helpers = require('./helpers')
, _ = require('lodash') , _ = require('lodash')
, Transaction = require('../transaction') , Transaction = require('../transaction')
...@@ -122,6 +121,7 @@ module.exports = (function() { ...@@ -122,6 +121,7 @@ module.exports = (function() {
this.accessors = { this.accessors = {
get: Utils._.camelize('get_' + this.as), get: Utils._.camelize('get_' + this.as),
set: Utils._.camelize('set_' + this.as), set: Utils._.camelize('set_' + this.as),
addMultiple: Utils._.camelize('add_' + this.as, this.target.options.language),
add: Utils._.camelize(Utils.singularize('add_' + this.as, this.target.options.language)), add: Utils._.camelize(Utils.singularize('add_' + this.as, this.target.options.language)),
create: Utils._.camelize(Utils.singularize('create_' + this.as, this.target.options.language)), create: Utils._.camelize(Utils.singularize('create_' + this.as, this.target.options.language)),
remove: Utils._.camelize(Utils.singularize('remove_' + this.as, this.target.options.language)), remove: Utils._.camelize(Utils.singularize('remove_' + this.as, this.target.options.language)),
...@@ -262,40 +262,26 @@ module.exports = (function() { ...@@ -262,40 +262,26 @@ module.exports = (function() {
obj[this.accessors.hasAll] = function(objects, options) { obj[this.accessors.hasAll] = function(objects, options) {
var instance = this; var instance = this;
var customEventEmitter = new Utils.CustomEventEmitter(function() { return instance[self.accessors.get](options).then(function(associatedObjects) {
instance[self.accessors.get](options) return Utils._.all(objects, function(o) {
.error(function(err) { customEventEmitter.emit('error', err) })
.success(function(associatedObjects) {
customEventEmitter.emit('success',
Utils._.all(objects, function(o) {
return Utils._.any(associatedObjects, function(associatedObject) { return Utils._.any(associatedObjects, function(associatedObject) {
return Utils._.all(associatedObject.identifiers, function(key, identifier) { return Utils._.all(associatedObject.identifiers, function(key, identifier) {
return o[identifier] == associatedObject[identifier]; return o[identifier] == associatedObject[identifier];
}); });
}) })
}) })
)
})
}) })
return customEventEmitter.run()
} }
obj[this.accessors.hasSingle] = function(o, options) { obj[this.accessors.hasSingle] = function(o, options) {
var instance = this var instance = this
var customEventEmitter = new Utils.CustomEventEmitter(function() { return instance[self.accessors.get](options).then(function(associatedObjects) {
instance[self.accessors.get](options) return Utils._.any(associatedObjects, function(associatedObject) {
.error(function(err){ customEventEmitter.emit('error', err)})
.success(function(associatedObjects) {
customEventEmitter.emit('success',
Utils._.any(associatedObjects, function(associatedObject) {
return Utils._.all(associatedObject.identifiers, function(key, identifier) { return Utils._.all(associatedObject.identifiers, function(key, identifier) {
return o[identifier] == associatedObject[identifier]; return o[identifier] == associatedObject[identifier];
}); });
}) })
)
}) })
})
return customEventEmitter.run()
} }
return this return this
} }
...@@ -303,56 +289,55 @@ module.exports = (function() { ...@@ -303,56 +289,55 @@ module.exports = (function() {
HasMany.prototype.injectSetter = function(obj) { HasMany.prototype.injectSetter = function(obj) {
var self = this var self = this
obj[this.accessors.set] = function(newAssociatedObjects, defaultAttributes) { obj[this.accessors.set] = function (newAssociatedObjects, additionalAttributes) {
if (newAssociatedObjects === null) { if (newAssociatedObjects === null) {
newAssociatedObjects = [] newAssociatedObjects = []
} }
var instance = this var instance = this
// define the returned customEventEmitter, which will emit the success event once everything is done return instance[self.accessors.get]({
return new Utils.CustomEventEmitter(function(emitter) { transaction: (additionalAttributes || {}).transaction
instance[self.accessors.get]({ }).then(function(oldAssociatedObjects) {
transaction: (defaultAttributes || {}).transaction
})
.success(function(oldAssociatedObjects) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked
new Class(self, instance).injectSetter(emitter, oldAssociatedObjects, newAssociatedObjects, defaultAttributes) return new Class(self, instance).injectSetter(oldAssociatedObjects, newAssociatedObjects, additionalAttributes)
}) })
.proxy(emitter, {events: ['error', 'sql']})
}).run()
} }
obj[this.accessors.add] = function(newInstance, additionalAttributes) { obj[this.accessors.add] = function (newInstance, additionalAttributes) {
var instance = this var instance = this
, primaryKey = newInstance.Model.primaryKeyAttribute , primaryKey = newInstance.Model.primaryKeyAttribute
, where = new Utils.where(self.target.rawAttributes[primaryKey], newInstance[primaryKey]) , where = new Utils.where(self.target.rawAttributes[primaryKey], newInstance[primaryKey])
return new Utils.CustomEventEmitter(function(emitter) { if (Array.isArray(newInstance)) {
instance[self.accessors.get]({ return obj[self.accessors.addMultiple](newInstance, additionalAttributes)
} else {
return instance[self.accessors.get]({
where: where, where: where,
transaction: (additionalAttributes || {}).transaction transaction: (additionalAttributes || {}).transaction
}) }).then(function(currentAssociatedObjects) {
.proxy(emitter, {events: ['error', 'sql']})
.success(function(currentAssociatedObjects) {
if (currentAssociatedObjects.length === 0 || Object(self.through) === self.through) { if (currentAssociatedObjects.length === 0 || Object(self.through) === self.through) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked
new Class(self, instance).injectAdder(emitter, newInstance, additionalAttributes, !!currentAssociatedObjects.length) return new Class(self, instance).injectAdder(newInstance, additionalAttributes, !!currentAssociatedObjects.length)
} else { } else {
emitter.emit('success', newInstance); return Utils.Promise.resolve(newInstance)
} }
}) })
}).run() }
}
obj[this.accessors.addMultiple] = function (newInstances, additionalAttributes) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked
return new Class(self, this).injectSetter([], newInstances, additionalAttributes)
} }
obj[this.accessors.remove] = function(oldAssociatedObject, options) {
obj[this.accessors.remove] = function (oldAssociatedObject, options) {
var instance = this var instance = this
return new Utils.CustomEventEmitter(function(emitter) { return instance[self.accessors.get]({
instance[self.accessors.get]({
transaction: (options || {}).transaction transaction: (options || {}).transaction
}).success(function(currentAssociatedObjects) { }).then(function(currentAssociatedObjects) {
var newAssociations = [] var newAssociations = []
, oldAssociations = []
currentAssociatedObjects.forEach(function(association) { currentAssociatedObjects.forEach(function(association) {
if (!Utils._.isEqual(oldAssociatedObject.identifiers, association.identifiers)) { if (!Utils._.isEqual(oldAssociatedObject.identifiers, association.identifiers)) {
...@@ -360,36 +345,8 @@ module.exports = (function() { ...@@ -360,36 +345,8 @@ module.exports = (function() {
} }
}) })
var tick = 0 return instance[self.accessors.set](newAssociations)
var next = function(err, i) {
if (!!err || i >= oldAssociations.length) {
return run(err)
}
oldAssociations[i].destroy().error(function(err) {
next(err)
})
.success(function() {
tick++
next(null, tick)
})
}
var run = function(err) {
if (!!err) {
return emitter.emit('error', err)
}
instance[self.accessors.set](newAssociations).proxy(emitter)
}
if (oldAssociations.length > 0) {
next(null, tick)
} else {
run()
}
}) })
}).run()
} }
return this return this
...@@ -407,16 +364,10 @@ module.exports = (function() { ...@@ -407,16 +364,10 @@ module.exports = (function() {
} }
if (Object(self.through) === self.through) { if (Object(self.through) === self.through) {
return new Utils.CustomEventEmitter(function(emitter) {
// Create the related model instance // Create the related model instance
self.target return self.target.create(values, fieldsOrOptions).then(function(newAssociatedObject) {
.create(values, fieldsOrOptions) return instance[self.accessors.add](newAssociatedObject, options)
.proxy(emitter, { events: ['error', 'sql'] })
.success(function(newAssociatedObject) {
instance[self.accessors.add](newAssociatedObject, options)
.proxy(emitter)
}) })
}).run()
} else { } else {
values[self.identifier] = instance.get(self.source.primaryKeyAttribute); values[self.identifier] = instance.get(self.source.primaryKeyAttribute);
return self.target.create(values, fieldsOrOptions) return self.target.create(values, fieldsOrOptions)
......
var Utils = require("./../utils") var Utils = require("./../utils")
, DataTypes = require('./../data-types')
, Helpers = require("./helpers") , Helpers = require("./helpers")
, Transaction = require("../transaction") , Transaction = require("../transaction")
...@@ -118,15 +117,9 @@ module.exports = (function() { ...@@ -118,15 +117,9 @@ module.exports = (function() {
options.transaction = fieldsOrOptions.transaction options.transaction = fieldsOrOptions.transaction
} }
return new Utils.CustomEventEmitter(function(emitter) { return association.target.create(values, fieldsOrOptions).then(function(associationInstance) {
association.target return instance[association.accessors.set](associationInstance, options)
.create(values, fieldsOrOptions)
.proxy(emitter, { events: ['error', 'sql'] })
.success(function(associationInstance) {
instance[association.accessors.set](associationInstance, options)
.proxy(emitter)
}) })
}).run()
} }
return this return this
......
...@@ -69,7 +69,7 @@ var Mixin = module.exports = function(){} ...@@ -69,7 +69,7 @@ var Mixin = module.exports = function(){}
* * set[AS] - for example setProfile(instance, options). Options are passed to `target.save` * * set[AS] - for example setProfile(instance, options). Options are passed to `target.save`
* * create[AS] - for example createProfile(value, options). Builds and saves a new instance of the associated model. Values and options are passed on to `target.create` * * create[AS] - for example createProfile(value, options). Builds and saves a new instance of the associated model. Values and options are passed on to `target.create`
* *
* All methods return an event emitter. * All methods return a promise
* *
* @param {Model} target * @param {Model} target
* @param {object} [options] * @param {object} [options]
...@@ -110,7 +110,7 @@ Mixin.hasOne = function(targetModel, options) { ...@@ -110,7 +110,7 @@ Mixin.hasOne = function(targetModel, options) {
* * set[AS] - for example setUser(instance, options). Options are passed to this.save * * set[AS] - for example setUser(instance, options). Options are passed to this.save
* * create[AS] - for example createUser(value, options). Builds and saves a new instance of the associated model. Values and options are passed on to target.create * * create[AS] - for example createUser(value, options). Builds and saves a new instance of the associated model. Values and options are passed on to target.create
* *
* All methods return an event emitter. * All methods return a promise
* *
* @param {Model} target * @param {Model} target
* @param {object} [options] * @param {object} [options]
...@@ -158,13 +158,14 @@ Mixin.belongsTo = function(targetModel, options) { ...@@ -158,13 +158,14 @@ Mixin.belongsTo = function(targetModel, options) {
* *
* * get[AS] - for example getPictures(). * * get[AS] - for example getPictures().
* * set[AS] - for example setPictures(instances, defaultAttributes|options). Update the associations. All currently associated models that are not in instances will be removed. * * set[AS] - for example setPictures(instances, defaultAttributes|options). Update the associations. All currently associated models that are not in instances will be removed.
* * add[AS] - for example addPicture(instance, defaultAttributes|options). Add another association. * * 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. * * 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
* * has[AS] - for example hasPicture(instance). Is source associated to this target? * * 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? * * has[AS] [plural] - for example hasPictures(instances). Is source associated to all these targets?
* *
* All methods return an event emitter. * All methods return a promise
* *
* If you use a through model with custom attributes, these attributes can be set when adding / setting new associations in two ways. Consider users and projects from before * If you use a through model with custom attributes, these attributes can be set when adding / setting new associations in two ways. Consider users and projects from before
* with a join table that stores whether the project has been started yet: * with a join table that stores whether the project has been started yet:
......
...@@ -293,6 +293,35 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -293,6 +293,35 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
describe('addMultipleAssociations', function () {
it('adds associations without removing the current ones', function () {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
Task.hasMany(User)
return this.sequelize.sync({ force: true }).then(function() {
return User.bulkCreate([
{ username: 'foo '},
{ username: 'bar '},
{ username: 'baz '}
]).then(function () {
return Task.create({ title: 'task' }).then(function (task) {
return User.findAll().then(function(users) {
return task.setUsers([users[0]]).then(function () {
return task.addUsers([users[1], users[2]]).then(function () {
return task.getUsers().then(function (users) {
expect(users).to.have.length(3)
})
})
})
})
})
})
})
})
})
it("clears associations when passing null to the set-method with omitNull set to true", function(done) { it("clears associations when passing null to the set-method with omitNull set to true", function(done) {
this.sequelize.options.omitNull = true this.sequelize.options.omitNull = true
...@@ -923,6 +952,36 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -923,6 +952,36 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
describe('addMultipleAssociations', function () {
it('adds associations without removing the current ones', function () {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
User.hasMany(Task)
Task.hasMany(User)
return this.sequelize.sync({ force: true }).then(function() {
return User.bulkCreate([
{ username: 'foo '},
{ username: 'bar '},
{ username: 'baz '}
]).then(function () {
return Task.create({ title: 'task' }).then(function (task) {
return User.findAll().then(function(users) {
return task.setUsers([users[0]]).then(function () {
return task.addUsers([users[1], users[2]]).then(function () {
return task.getUsers().then(function (users) {
expect(users).to.have.length(3)
})
})
})
})
})
})
})
})
})
describe('optimizations using bulk create, destroy and update', function () { describe('optimizations using bulk create, destroy and update', function () {
beforeEach(function (done) { beforeEach(function (done) {
this.User = this.sequelize.define('User', { username: DataTypes.STRING }, {timestamps: false}) this.User = this.sequelize.define('User', { username: DataTypes.STRING }, {timestamps: false})
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!