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

Commit 3ced2aaa by Mick Hansen

Merge pull request #1747 from sequelize/setWithId

Add ability to set and add associations by model id instead of model instance
2 parents d14c24b0 85ab07cb
...@@ -5,6 +5,7 @@ Notice: All 1.7.x changes are present in 2.0.x aswell ...@@ -5,6 +5,7 @@ Notice: All 1.7.x changes are present in 2.0.x aswell
- [FEATURE] There is now basic support for assigning a field name to an attribute `name: {type: DataTypes.STRING, field: 'full_name'}` - [FEATURE] There is now basic support for assigning a field name to an attribute `name: {type: DataTypes.STRING, field: 'full_name'}`
- [FEATURE] It's now possible to add multiple relations to a hasMany association, modelInstance.addRelations([otherInstanceA, otherInstanceB]) - [FEATURE] It's now possible to add multiple relations to a hasMany association, modelInstance.addRelations([otherInstanceA, otherInstanceB])
- [FEATURE] `define()` stores models in `sequelize.models` Object e.g. `sequelize.models.MyModel` - [FEATURE] `define()` stores models in `sequelize.models` Object e.g. `sequelize.models.MyModel`
- [FEATURE] The `set` / `add` / `has` methods for associations now allow you to pass the value of a primary key, instead of a full Instance object, like so: `user.addTask(15);`.
- [BUG] An error is now thrown if an association would create a naming conflict between the association and the foreign key when doing eager loading. Closes [#1272](https://github.com/sequelize/sequelize/issues/1272) - [BUG] An error is now thrown if an association would create a naming conflict between the association and the foreign key when doing eager loading. Closes [#1272](https://github.com/sequelize/sequelize/issues/1272)
- [INTERNALS] `bulkDeleteQuery` was removed from the MySQL / abstract query generator, since it was never used internally. Please use `deleteQuery` instead. - [INTERNALS] `bulkDeleteQuery` was removed from the MySQL / abstract query generator, since it was never used internally. Please use `deleteQuery` instead.
......
...@@ -88,7 +88,12 @@ module.exports = (function() { ...@@ -88,7 +88,12 @@ module.exports = (function() {
var association = this var association = this
instancePrototype[this.accessors.set] = function(associatedInstance, options) { instancePrototype[this.accessors.set] = function(associatedInstance, options) {
this.set(association.identifier, associatedInstance ? associatedInstance[association.targetIdentifier] : null) var value = associatedInstance
if (associatedInstance instanceof association.target.Instance) {
value = associatedInstance[association.targetIdentifier]
}
this.set(association.identifier, value)
options = Utils._.extend({ options = Utils._.extend({
fields: [ association.identifier ], fields: [ association.identifier ],
......
...@@ -10,14 +10,11 @@ module.exports = (function() { ...@@ -10,14 +10,11 @@ module.exports = (function() {
this.QueryInterface = instance.QueryInterface this.QueryInterface = instance.QueryInterface
} }
HasManyDoubleLinked.prototype.injectGetter = function(options) { HasManyDoubleLinked.prototype.injectGetter = function(options, queryOptions) {
var self = this var self = this
, through = self.association.through , through = self.association.through
, 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
......
...@@ -10,9 +10,7 @@ module.exports = (function() { ...@@ -10,9 +10,7 @@ module.exports = (function() {
this.source = this.association.source this.source = this.association.source
} }
HasManySingleLinked.prototype.injectGetter = function(options) { HasManySingleLinked.prototype.injectGetter = function(options, queryOptions) {
options = options || {}
options.where = new Utils.and([ options.where = new Utils.and([
new Utils.where( new Utils.where(
this.target.rawAttributes[this.association.identifier], this.target.rawAttributes[this.association.identifier],
...@@ -21,7 +19,7 @@ module.exports = (function() { ...@@ -21,7 +19,7 @@ module.exports = (function() {
options.where options.where
]) ])
return this.association.target.all(options) return this.association.target.all(options, queryOptions)
} }
HasManySingleLinked.prototype.injectSetter = function(oldAssociations, newAssociations, defaultAttributes) { HasManySingleLinked.prototype.injectSetter = function(oldAssociations, newAssociations, defaultAttributes) {
......
...@@ -177,8 +177,8 @@ module.exports = (function() { ...@@ -177,8 +177,8 @@ module.exports = (function() {
} }
// remove any PKs previously defined by sequelize // remove any PKs previously defined by sequelize
Utils._.each(this.through.attributes, function(dataTypeString, attributeName) { Utils._.each(this.through.rawAttributes, function(attribute, attributeName) {
if (dataTypeString.toString().indexOf('PRIMARY KEY') !== -1 && self.through.rawAttributes[attributeName]._autoGenerated === true) { if (attribute.primaryKey === true && attribute._autoGenerated === true) {
delete self.through.rawAttributes[attributeName] delete self.through.rawAttributes[attributeName]
primaryKeyDeleted = true primaryKeyDeleted = true
} }
...@@ -256,88 +256,153 @@ module.exports = (function() { ...@@ -256,88 +256,153 @@ module.exports = (function() {
} }
HasMany.prototype.injectGetter = function(obj) { HasMany.prototype.injectGetter = function(obj) {
var self = this var association = this
obj[this.accessors.get] = function(options) { obj[this.accessors.get] = function(options, queryOptions) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked options = options || {}
return new Class(self, this).injectGetter(options) queryOptions = queryOptions || {}
var Class = Object(association.through) === association.through ? HasManyDoubleLinked : HasManySingleLinked
return new Class(association, this).injectGetter(options, queryOptions)
} }
obj[this.accessors.hasAll] = function(objects, options) { obj[this.accessors.hasAll] = function(instances, options) {
var instance = this; var instance = this
return instance[self.accessors.get](options).then(function(associatedObjects) { , where
return Utils._.all(objects, function(o) {
return Utils._.any(associatedObjects, function(associatedObject) { options = options || {}
return Utils._.all(associatedObject.identifiers, function(key, identifier) {
return o[identifier] == associatedObject[identifier]; instances.forEach(function (instance) {
}); if (instance instanceof association.target.Instance) {
}) where = new Utils.or([where, instance.primaryKeyValues])
}) } else {
var _where = {}
_where[association.target.primaryKeyAttribute] = instance
where = new Utils.or([where, _where])
}
})
options.where = new Utils.and([
where,
options.where
])
return instance[association.accessors.get](
options,
{ raw: true }
).then(function(associatedObjects) {
return associatedObjects.length === instances.length
}) })
} }
obj[this.accessors.hasSingle] = function(o, options) { obj[this.accessors.hasSingle] = function(param, options) {
var instance = this var instance = this
return instance[self.accessors.get](options).then(function(associatedObjects) { , where
return Utils._.any(associatedObjects, function(associatedObject) {
return Utils._.all(associatedObject.identifiers, function(key, identifier) { options = options || {}
return o[identifier] == associatedObject[identifier];
}); if (param instanceof association.target.Instance) {
}) where = param.primaryKeyValues
} else {
where = {}
where[association.target.primaryKeyAttribute] = param
}
options.where = new Utils.and([
where,
options.where
])
return instance[association.accessors.get](
options,
{ raw: true }
).then(function(associatedObjects) {
return associatedObjects.length !== 0
}) })
} }
return this return this
} }
HasMany.prototype.injectSetter = function(obj) { HasMany.prototype.injectSetter = function(obj) {
var self = this var association = this
, primaryKeyAttribute = association.target.primaryKeyAttribute
obj[this.accessors.set] = function (newAssociatedObjects, additionalAttributes) { obj[this.accessors.set] = function (newAssociatedObjects, additionalAttributes) {
if (newAssociatedObjects === null) { if (newAssociatedObjects === null) {
newAssociatedObjects = [] newAssociatedObjects = []
} else {
newAssociatedObjects = newAssociatedObjects.map(function (newAssociatedObject) {
if (!(newAssociatedObject instanceof association.target.Instance)) {
var tmpInstance = {}
tmpInstance[primaryKeyAttribute] = newAssociatedObject
return association.target.build(tmpInstance, {
isNewRecord: false
})
}
return newAssociatedObject
})
} }
var instance = this var instance = this
return instance[self.accessors.get]({ return instance[association.accessors.get]({
transaction: (additionalAttributes || {}).transaction transaction: (additionalAttributes || {}).transaction
}).then(function(oldAssociatedObjects) { }).then(function(oldAssociatedObjects) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked var Class = Object(association.through) === association.through ? HasManyDoubleLinked : HasManySingleLinked
return new Class(self, instance).injectSetter(oldAssociatedObjects, newAssociatedObjects, additionalAttributes) return new Class(association, instance).injectSetter(oldAssociatedObjects, newAssociatedObjects, additionalAttributes)
}) })
} }
obj[this.accessors.add] = function (newInstance, additionalAttributes) { obj[this.accessors.add] = function (newInstance, additionalAttributes) {
var instance = this var instance = this
, primaryKey = newInstance.Model.primaryKeyAttribute , primaryKeyAttribute = association.target.primaryKeyAttribute
, where = new Utils.where(self.target.rawAttributes[primaryKey], newInstance[primaryKey])
if (!(newInstance instanceof association.target.Instance)) {
var tmpInstance = {}
tmpInstance[primaryKeyAttribute] = newInstance
newInstance = association.target.build(tmpInstance, {
isNewRecord: false
})
}
if (Array.isArray(newInstance)) { if (Array.isArray(newInstance)) {
return obj[self.accessors.addMultiple](newInstance, additionalAttributes) return obj[association.accessors.addMultiple](newInstance, additionalAttributes)
} else { } else {
return instance[self.accessors.get]({ return instance[association.accessors.get]({
where: where, where: newInstance.primaryKeyValues,
transaction: (additionalAttributes || {}).transaction transaction: (additionalAttributes || {}).transaction
}).then(function(currentAssociatedObjects) { }).then(function(currentAssociatedObjects) {
if (currentAssociatedObjects.length === 0 || Object(self.through) === self.through) { if (currentAssociatedObjects.length === 0 || Object(association.through) === association.through) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked var Class = Object(association.through) === association.through ? HasManyDoubleLinked : HasManySingleLinked
return new Class(self, instance).injectAdder(newInstance, additionalAttributes, !!currentAssociatedObjects.length) return new Class(association, instance).injectAdder(newInstance, additionalAttributes, !!currentAssociatedObjects.length)
} else { } else {
return Utils.Promise.resolve(newInstance) return Utils.Promise.resolve(currentAssociatedObjects[0])
} }
}) })
} }
} }
obj[this.accessors.addMultiple] = function (newInstances, additionalAttributes) { obj[this.accessors.addMultiple] = function (newInstances, additionalAttributes) {
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked var primaryKeyAttribute = association.target.primaryKeyAttribute
return new Class(self, this).injectSetter([], newInstances, additionalAttributes)
newInstances = newInstances.map(function (newInstance) {
if (!(newInstance instanceof association.target.Instance)) {
var tmpInstance = {}
tmpInstance[primaryKeyAttribute] = newInstance
return association.target.build(tmpInstance, {
isNewRecord: false
})
}
return newInstance
})
var Class = Object(association.through) === association.through ? HasManyDoubleLinked : HasManySingleLinked
return new Class(association, 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 instance[self.accessors.get]({ return instance[association.accessors.get]({
transaction: (options || {}).transaction transaction: (options || {}).transaction
}).then(function(currentAssociatedObjects) { }).then(function(currentAssociatedObjects) {
var newAssociations = [] var newAssociations = []
...@@ -348,7 +413,7 @@ module.exports = (function() { ...@@ -348,7 +413,7 @@ module.exports = (function() {
} }
}) })
return instance[self.accessors.set](newAssociations) return instance[association.accessors.set](newAssociations)
}) })
} }
...@@ -356,7 +421,7 @@ module.exports = (function() { ...@@ -356,7 +421,7 @@ module.exports = (function() {
} }
HasMany.prototype.injectCreator = function(obj) { HasMany.prototype.injectCreator = function(obj) {
var self = this var association = this
obj[this.accessors.create] = function(values, fieldsOrOptions) { obj[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this var instance = this
...@@ -366,14 +431,14 @@ module.exports = (function() { ...@@ -366,14 +431,14 @@ module.exports = (function() {
options.transaction = fieldsOrOptions.transaction options.transaction = fieldsOrOptions.transaction
} }
if (Object(self.through) === self.through) { if (Object(association.through) === association.through) {
// Create the related model instance // Create the related model instance
return self.target.create(values, fieldsOrOptions).then(function(newAssociatedObject) { return association.target.create(values, fieldsOrOptions).then(function(newAssociatedObject) {
return instance[self.accessors.add](newAssociatedObject, options) return instance[association.accessors.add](newAssociatedObject, options)
}) })
} else { } else {
values[self.identifier] = instance.get(self.source.primaryKeyAttribute); values[association.identifier] = instance.get(association.source.primaryKeyAttribute);
return self.target.create(values, fieldsOrOptions) return association.target.create(values, fieldsOrOptions)
} }
} }
...@@ -385,7 +450,7 @@ module.exports = (function() { ...@@ -385,7 +450,7 @@ module.exports = (function() {
* This is done because we need to keep the foreign key if another association * This is done because we need to keep the foreign key if another association
* is depending on it. * is depending on it.
* *
* @param {DaoFactory} daoFactory The source or target DaoFactory of this assocation * @param {DaoFactory} daoFactory The source or target DaoFactory of this association
* @param {[type]} identifier The name of the foreign key identifier * @param {[type]} identifier The name of the foreign key identifier
* @return {Boolean} Whether or not the deletion of the foreign key is ok. * @return {Boolean} Whether or not the deletion of the foreign key is ok.
*/ */
......
...@@ -101,6 +101,13 @@ module.exports = (function() { ...@@ -101,6 +101,13 @@ module.exports = (function() {
} }
}).then(function () { }).then(function () {
if (associatedInstance) { if (associatedInstance) {
if (!(associatedInstance instanceof association.target.Instance)) {
var tmpInstance = {}
tmpInstance[association.target.primaryKeyAttribute] = associatedInstance
associatedInstance = association.target.build(tmpInstance, {
isNewRecord: false
})
}
associatedInstance.set(association.identifier, instance.get(association.sourceIdentifier)) associatedInstance.set(association.identifier, instance.get(association.sourceIdentifier))
return associatedInstance.save(options) return associatedInstance.save(options)
} }
......
...@@ -44,8 +44,21 @@ var Utils = require("./../utils") ...@@ -44,8 +44,21 @@ var Utils = require("./../utils")
* } * }
* }) * })
* ``` * ```
*
* There are several methods to update and add new assoications. Continuing with our example of users and pictures:
* ```js
* user.addPicture(p) // Add a single picture
* user.setPictures([p1, p2]) // Associate user with ONLY these two picture, all other associations will be deleted
* user.addPictures([p1, p2]) // Associate user with these two pictures, but don't touch any current associations
* ```
*
* You don't have to pass in a complete object to the association functions, if your associated model has a single primary key:
*
* ```js
* user.addPicture(req.query.pid) // Here pid is just an integer, representing the primary key of the picture
* ```
* *
* In the above we specify that a user belongs to his profile picture. Conceptually, this might not make sense, * In the example above we have specified that a user belongs to his profile picture. Conceptually, this might not make sense,
* but since we want to add the foreign key to the user model this is the way to do it. * but since we want to add the foreign key to the user model this is the way to do it.
* Note how we also specified `constraints: false` for profile picture. This is because we add a foreign key from * Note how we also specified `constraints: false` for profile picture. This is because we add a foreign key from
* user to picture (profilePictureId), and from picture to user (userId). If we were to add foreign keys to both, it would * user to picture (profilePictureId), and from picture to user (userId). If we were to add foreign keys to both, it would
......
...@@ -184,6 +184,25 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -184,6 +184,25 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
}) })
}) })
it('supports passing the primary key instead of an object', function () {
var User = this.sequelize.define('UserXYZ', { username: DataTypes.STRING })
, Task = this.sequelize.define('TaskXYZ', { title: DataTypes.STRING })
Task.belongsTo(User)
return this.sequelize.sync({ force :true }).then(function () {
return User.create({ id: 15, username: 'jansemand' }).then(function (user) {
return Task.create({}).then(function (task) {
return task.setUserXYZ(user.id).then(function () {
return task.getUserXYZ().then(function (user) {
expect(user.username).to.equal('jansemand')
})
})
})
})
})
})
it('should not clobber atributes', function (done) { it('should not clobber atributes', function (done) {
var Comment = this.sequelize.define('comment', { var Comment = this.sequelize.define('comment', {
text: DataTypes.STRING text: DataTypes.STRING
......
...@@ -113,6 +113,25 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -113,6 +113,25 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
it('answers true if the label has been assigned when passing a primary key instead of an object', function() {
var self = this
return this.sequelize.Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).spread(function (article, label1, label2) {
return article.addLabel(label1).then(function () {
return self.sequelize.Promise.all([
article.hasLabel(label1.id),
article.hasLabel(label2.id),
]).spread(function (hasLabel1, hasLabel2) {
expect(hasLabel1).to.be.true
expect(hasLabel2).to.be.false
})
})
})
})
}) })
describe('hasAll', function() { describe('hasAll', function() {
...@@ -181,6 +200,20 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -181,6 +200,20 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
it('answers false if only some labels have been assigned when passing a primary key instead of an object', function() {
return this.sequelize.Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).spread(function (article, label1, label2) {
return article.addLabel(label1).then(function() {
return article.hasLabels([label1.id, label2.id]).then(function(result) {
expect(result).to.be.false
})
})
})
})
it('answers true if all label have been assigned', function(done) { it('answers true if all label have been assigned', function(done) {
var chainer = new Sequelize.Utils.QueryChainer([ var chainer = new Sequelize.Utils.QueryChainer([
this.Article.create({ title: 'Article' }), this.Article.create({ title: 'Article' }),
...@@ -197,6 +230,20 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -197,6 +230,20 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
it('answers true if all label have been assigned when passing a primary key instead of an object', function() {
return this.sequelize.Promise.all([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
]).spread(function (article, label1, label2) {
return article.setLabels([label1, label2]).then(function() {
return article.hasLabels([label1.id, label2.id]).then(function(result) {
expect(result).to.be.true
})
})
})
})
}) })
describe('setAssociations', function() { describe('setAssociations', function() {
...@@ -257,6 +304,30 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -257,6 +304,30 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
it('supports passing the primary key instead of an object', function () {
var Article = this.sequelize.define('Article', { title: DataTypes.STRING })
, Label = this.sequelize.define('Label', { text: DataTypes.STRING })
Article.hasMany(Label)
return this.sequelize.sync({ force :true }).then(function () {
return Article.create({}).then(function (article) {
return Label.create({ text: 'label one' }).then(function (label1) {
return Label.create({ text: 'label two' }).then(function (label2) {
return article.addLabel(label1.id).then(function () {
return article.setLabels([label2.id]).then(function () {
return article.getLabels().then(function (labels) {
expect(labels).to.have.length(1)
expect(labels[0].text).to.equal('label two')
})
})
})
})
})
})
})
})
}) })
describe('addAssociations', function() { describe('addAssociations', function() {
...@@ -291,6 +362,25 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -291,6 +362,25 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
it('supports passing the primary key instead of an object', function () {
var Article = this.sequelize.define('Article', { 'title': DataTypes.STRING })
, Label = this.sequelize.define('Label', { 'text': DataTypes.STRING })
Article.hasMany(Label)
return this.sequelize.sync({ force :true }).then(function () {
return Article.create({}).then(function (article) {
return Label.create({ text: 'label one' }).then(function (label) {
return article.addLabel(label.id).then(function () {
return article.getLabels().then(function (labels) {
expect(labels[0].text).to.equal('label one') // Make sure that we didn't modify one of the other attributes while building / saving a new instance
})
})
})
})
})
})
}) })
describe('addMultipleAssociations', function () { describe('addMultipleAssociations', function () {
...@@ -871,6 +961,31 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -871,6 +961,31 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
it('supports passing the primary key instead of an object', 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.create({ id: 12 }).then(function (user) {
return Task.create({ id: 50, title: 'get started' }).then(function (task1) {
return Task.create({ id: 5, title: 'wat' }).then(function (task2) {
return user.addTask(task1.id).then(function () {
return user.setTasks([task2.id]).then(function () {
return user.getTasks().then(function (tasks) {
expect(tasks).to.have.length(1)
expect(tasks[0].title).to.equal('wat')
})
})
})
})
})
})
})
})
}) })
describe('createAssociations', function() { describe('createAssociations', function() {
...@@ -950,6 +1065,26 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -950,6 +1065,26 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
it('supports passing the primary key instead of an object', 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.create({ id: 12 }).then(function (user) {
return Task.create({ id: 50, title: 'get started' }).then(function (task) {
return user.addTask(task.id).then(function () {
return user.getTasks().then(function (tasks) {
expect(tasks[0].title).to.equal('get started')
})
})
})
})
})
})
}) })
describe('addMultipleAssociations', function () { describe('addMultipleAssociations', function () {
......
...@@ -166,6 +166,25 @@ describe(Support.getTestDialectTeaser("HasOne"), function() { ...@@ -166,6 +166,25 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
}) })
}) })
}) })
it('supports passing the primary key instead of an object', function () {
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING })
, Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING })
User.hasOne(Task)
return this.sequelize.sync({ force :true }).then(function () {
return User.create({}).then(function (user) {
return Task.create({ id: 19, title: 'task it!' }).then(function (task) {
return user.setTaskXYZ(task.id).then(function () {
return user.getTaskXYZ().then(function (task) {
expect(task.title).to.equal('task it!')
})
})
})
})
})
})
}) })
describe('createAssociation', function() { describe('createAssociation', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!