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

Commit feca1473 by Sascha Depold

belongsTo, hasOne and hasMany working for find.

1 parent 830b86b3
...@@ -19,11 +19,11 @@ Mixin.hasOne = function(associatedDAO, options) { ...@@ -19,11 +19,11 @@ Mixin.hasOne = function(associatedDAO, options) {
Mixin.belongsTo = function(associatedDAO, options) { Mixin.belongsTo = function(associatedDAO, options) {
// the id is in this table // the id is in this table
var association = new BelongsTo(this, associatedDAO, Utils._.extend((options||{}), this.options)) var association = new BelongsTo(this, associatedDAO, Utils._.extend((options || {}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes() this.associations[association.associationAccessor] = association.injectAttributes()
association.injectGetter(this.DAO.prototype); association.injectGetter(this.DAO.prototype)
association.injectSetter(this.DAO.prototype); association.injectSetter(this.DAO.prototype)
return this return this
} }
...@@ -33,8 +33,8 @@ Mixin.hasMany = function(associatedDAO, options) { ...@@ -33,8 +33,8 @@ Mixin.hasMany = function(associatedDAO, options) {
var association = new HasMany(this, associatedDAO, Utils._.extend((options||{}), this.options)) var association = new HasMany(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes() this.associations[association.associationAccessor] = association.injectAttributes()
association.injectGetter(this.DAO.prototype); association.injectGetter(this.DAO.prototype)
association.injectSetter(this.DAO.prototype); association.injectSetter(this.DAO.prototype)
return this return this
} }
......
...@@ -146,9 +146,13 @@ module.exports = (function() { ...@@ -146,9 +146,13 @@ module.exports = (function() {
if ((typeof options === 'object') && (options.hasOwnProperty('include'))) { if ((typeof options === 'object') && (options.hasOwnProperty('include'))) {
var includes = options.include var includes = options.include
hasJoin = true hasJoin = true
options.include = {} options.include = {}
/*options.include =*/ includes.map(function(include) {
console.log(include instanceof DAOFactory)
})
includes.forEach(function(daoName) { includes.forEach(function(daoName) {
options.include[daoName] = this.daoFactoryManager.getDAO(daoName) options.include[daoName] = this.daoFactoryManager.getDAO(daoName)
...@@ -161,7 +165,10 @@ module.exports = (function() { ...@@ -161,7 +165,10 @@ module.exports = (function() {
this.options.whereCollection = options.where || null this.options.whereCollection = options.where || null
} }
return this.QueryInterface.select(this, this.tableName, options, { type: 'SELECT', hasJoin: hasJoin }) return this.QueryInterface.select(this, this.tableName, options, {
type: 'SELECT',
hasJoin: hasJoin
})
} }
//right now, the caller (has-many-double-linked) is in charge of the where clause //right now, the caller (has-many-double-linked) is in charge of the where clause
...@@ -175,8 +182,16 @@ module.exports = (function() { ...@@ -175,8 +182,16 @@ module.exports = (function() {
return this.QueryInterface.select(this, [this.tableName, joinTableName], optcpy, { type: 'SELECT' }) return this.QueryInterface.select(this, [this.tableName, joinTableName], optcpy, { type: 'SELECT' })
} }
/**
* Search for an instance.
*
* @param {Object} options Options to describe the scope of the search.
* @param {Array} include A list of associations which shall get eagerly loaded. Supported is either { include: [ DaoFactory1, DaoFactory2, ...] } or { include: [ { daoFactory: DaoFactory1, as: 'Alias' } ] }.
* @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*/
DAOFactory.prototype.find = function(options) { DAOFactory.prototype.find = function(options) {
var hasJoin = false var hasJoin = false
// no options defined? // no options defined?
// return an emitter which emits null // return an emitter which emits null
if ([null, undefined].indexOf(options) !== -1) { if ([null, undefined].indexOf(options) !== -1) {
...@@ -210,20 +225,13 @@ module.exports = (function() { ...@@ -210,20 +225,13 @@ module.exports = (function() {
options = { where: parsedId } options = { where: parsedId }
} else if (typeof options === 'object') { } else if (typeof options === 'object') {
var options = Utils._.clone(options) options = Utils._.clone(options)
var includes
if (options.hasOwnProperty('include')) { if (options.hasOwnProperty('include')) {
hasJoin = true hasJoin = true
includes = options.include
options.include = {}
includes.forEach(function(daoName) {
options.include[daoName] = this.daoFactoryManager.getDAO(daoName)
if (!options.include[daoName]) { options.include = options.include.map(function(include) {
options.include[daoName] = this.getAssociationByAlias(daoName).target return validateIncludedElement.call(this, include)
}
}.bind(this)) }.bind(this))
} }
...@@ -233,7 +241,11 @@ module.exports = (function() { ...@@ -233,7 +241,11 @@ module.exports = (function() {
options.limit = 1 options.limit = 1
return this.QueryInterface.select(this, this.tableName, options, { plain: true, type: 'SELECT', hasJoin: hasJoin }) return this.QueryInterface.select(this, this.tableName, options, {
plain: true,
type: 'SELECT',
hasJoin: hasJoin
})
} }
DAOFactory.prototype.count = function(options) { DAOFactory.prototype.count = function(options) {
...@@ -260,7 +272,7 @@ module.exports = (function() { ...@@ -260,7 +272,7 @@ module.exports = (function() {
} }
DAOFactory.prototype.build = function(values, options) { DAOFactory.prototype.build = function(values, options) {
options = options || {isNewRecord: true} options = options || { isNewRecord: true }
var self = this var self = this
, instance = new this.DAO(values, this.options, options.isNewRecord) , instance = new this.DAO(values, this.options, options.isNewRecord)
...@@ -283,16 +295,16 @@ module.exports = (function() { ...@@ -283,16 +295,16 @@ module.exports = (function() {
}).success(function (instance) { }).success(function (instance) {
if (instance === null) { if (instance === null) {
for (var attrname in defaults) { for (var attrname in defaults) {
params[attrname] = defaults[attrname]; params[attrname] = defaults[attrname]
} }
self.create(params) self.create(params)
.success(function (instance) { .success(function (instance) {
emitter.emit('success', instance) emitter.emit('success', instance)
}) })
.error( function (error) { .error( function (error) {
emitter.emit('error', error) emitter.emit('error', error)
}); })
} else { } else {
emitter.emit('success', instance) emitter.emit('success', instance)
} }
...@@ -368,6 +380,40 @@ module.exports = (function() { ...@@ -368,6 +380,40 @@ module.exports = (function() {
}.bind(this)) }.bind(this))
} }
var validateIncludedElement = function(include) {
if (include instanceof DAOFactory) {
include = { daoFactory: include, as: include.tableName }
}
if (typeof include === 'object') {
if (include.hasOwnProperty('daoFactory') && (include.hasOwnProperty('as'))) {
var usesAlias = (include.as !== include.daoFactory.tableName)
, association = (usesAlias ? this.getAssociationByAlias(include.as) : this.getAssociation(include.daoFactory))
// check if the current daoFactory is actually associated with the passed daoFactory
if (!!association) {
include.association = association
return include
} else {
var msg = include.daoFactory.name
if (usesAlias) {
msg += " (" + include.as + ")"
}
msg += " is not associated to " + this.name + "!"
throw new Error(msg)
}
} else {
throw new Error('Include malformed. Expected attributes: daoFactory, as')
}
} else {
throw new Error('Include unexpected. Element has to be either an instance of DAOFactory or an object.')
}
}
Utils._.extend(DAOFactory.prototype, require("./associations/mixin")) Utils._.extend(DAOFactory.prototype, require("./associations/mixin"))
return DAOFactory return DAOFactory
......
...@@ -131,49 +131,73 @@ module.exports = (function() { ...@@ -131,49 +131,73 @@ module.exports = (function() {
if (options.include) { if (options.include) {
var optAttributes = [options.table + '.*'] var optAttributes = [options.table + '.*']
for (var daoName in options.include) { options.include.forEach(function(include) {
if (options.include.hasOwnProperty(daoName)) { //SELECT `UserWithNames`.*, `Tasks`.`title` AS `Tasks.title`, `Tasks`.`id` AS `Tasks.id`, `Tasks`.`createdAt` AS `Tasks.createdAt`, `Tasks`.`updatedAt` AS `Tasks.updatedAt`, `TaskFROM `UserWithNames` LEFT OUTER JOIN `Tasks` ON `Tasks`.`UserWithNameId`=`UserWithNames`.`id` WHERE `UserWithNames`.`id`=1;
var dao = options.include[daoName] //SELECT `Tasks`.*, `Workers`.`name` AS `Workers.name`, `Workers`.`id` AS `Workers.id`, `Workers`.`createdAt` AS `Workers.createdAt`, `Workers`.`updatedAt` AS `Workers.updatedAt` FROM `Tasks` LEFT OUTER JOIN `Workers` ON `Workers`.`WorkerId` = `Tasks`.`id` WHERE `Tasks`.`id`=1;
, daoFactory = dao.daoFactoryManager.getDAO(tableName, { var attributes = Object.keys(include.daoFactory.attributes).map(function(attr) {
attribute: 'tableName' var template = Utils._.template("`<%= table %>`.`<%= attr %>` AS `<%= as %>.<%= attr %>`")
}) return template({
, _tableName = Utils.addTicks(dao.tableName) table: include.daoFactory.tableName,
, association = dao.getAssociation(daoFactory) as: include.as,
attr: attr
if (association.connectorDAO) { })
var foreignIdentifier = Object.keys(association.connectorDAO.rawAttributes).filter(function(attrName) { })
return (!!attrName.match(/.+Id$/) || !!attrName.match(/.+_id$/)) && (attrName !== association.identifier)
})[0] optAttributes = optAttributes.concat(attributes)
query += ' LEFT OUTER JOIN ' + Utils.addTicks(association.connectorDAO.tableName) + ' ON ' var joinQuery = " LEFT OUTER JOIN `<%= table %>` ON `<%= tableLeft %>`.`<%= attrLeft %>` = `<%= tableRight %>`.`<%= attrRight %>`"
query += Utils.addTicks(association.connectorDAO.tableName) + '.' query += Utils._.template(joinQuery)({
query += Utils.addTicks(foreignIdentifier) + '=' table: include.daoFactory.tableName,
query += Utils.addTicks(table) + '.' + Utils.addTicks('id') tableLeft: ((include.association.associationType === 'BelongsTo') ? include.daoFactory.tableName : tableName),
attrLeft: 'id',
query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON ' tableRight: ((include.association.associationType === 'BelongsTo') ? tableName : include.daoFactory.tableName),
query += Utils.addTicks(dao.tableName) + '.' attrRight: include.association.identifier
query += Utils.addTicks('id') + '=' })
query += Utils.addTicks(association.connectorDAO.tableName) + '.' + Utils.addTicks(association.identifier) })
} else {
query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON ' // for (var daoFactory in options.include) {
query += Utils.addTicks(association.associationType === 'BelongsTo' ? dao.tableName : tableName) + '.' // if (options.include.hasOwnProperty(daoFactory)) {
query += Utils.addTicks(association.identifier) + '=' // var dao = options.include[daoName]
query += Utils.addTicks(association.associationType === 'BelongsTo' ? tableName : dao.tableName) + '.' + Utils.addTicks('id') // , daoFactory = dao.daoFactoryManager.getDAO(tableName, {
} // attribute: 'tableName'
// })
var aliasAssoc = daoFactory.getAssociationByAlias(daoName) // , _tableName = Utils.addTicks(dao.tableName)
, aliasName = !!aliasAssoc ? Utils.addTicks(daoName) : _tableName // , association = dao.getAssociation(daoFactory)
optAttributes = optAttributes.concat( // if (association.connectorDAO) {
Object.keys(dao.attributes).map(function(attr) { // var foreignIdentifier = Object.keys(association.connectorDAO.rawAttributes).filter(function(attrName) {
return '' + // return (!!attrName.match(/.+Id$/) || !!attrName.match(/.+_id$/)) && (attrName !== association.identifier)
[_tableName, Utils.addTicks(attr)].join('.') + // })[0]
' AS ' +
Utils.addTicks([aliasName, attr].join('.')) // query += ' LEFT OUTER JOIN ' + Utils.addTicks(association.connectorDAO.tableName) + ' ON '
}) // query += Utils.addTicks(association.connectorDAO.tableName) + '.'
) // query += Utils.addTicks(foreignIdentifier) + '='
} // query += Utils.addTicks(table) + '.' + Utils.addTicks('id')
}
// query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
// query += Utils.addTicks(dao.tableName) + '.'
// query += Utils.addTicks('id') + '='
// query += Utils.addTicks(association.connectorDAO.tableName) + '.' + Utils.addTicks(association.identifier)
// } else {
// query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
// query += Utils.addTicks(association.associationType === 'BelongsTo' ? dao.tableName : tableName) + '.'
// query += Utils.addTicks(association.identifier) + '='
// query += Utils.addTicks(association.associationType === 'BelongsTo' ? tableName : dao.tableName) + '.' + Utils.addTicks('id')
// }
// var aliasAssoc = daoFactory.getAssociationByAlias(daoName)
// , aliasName = !!aliasAssoc ? Utils.addTicks(daoName) : _tableName
// optAttributes = optAttributes.concat(
// Object.keys(dao.attributes).map(function(attr) {
// return '' +
// [_tableName, Utils.addTicks(attr)].join('.') +
// ' AS ' +
// Utils.addTicks([aliasName, attr].join('.'))
// })
// )
// }
// }
options.attributes = optAttributes.join(', ') options.attributes = optAttributes.join(', ')
} }
......
...@@ -199,13 +199,14 @@ module.exports = (function() { ...@@ -199,13 +199,14 @@ module.exports = (function() {
QueryInterface.prototype.select = function(factory, tableName, options, queryOptions) { QueryInterface.prototype.select = function(factory, tableName, options, queryOptions) {
var sql = this.QueryGenerator.selectQuery(tableName, options) var sql = this.QueryGenerator.selectQuery(tableName, options)
queryOptions = Utils._.extend({}, queryOptions, { include: options.include })
return queryAndEmit.call(this, [sql, factory, queryOptions], 'select') return queryAndEmit.call(this, [sql, factory, queryOptions], 'select')
} }
QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelector) { QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelector) {
var self = this var self = this
if (attributeSelector == undefined) { if (attributeSelector === undefined) {
throw new Error('Please pass an attribute selector!') throw new Error('Please pass an attribute selector!')
} }
......
...@@ -466,417 +466,544 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -466,417 +466,544 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}.bind(this)) }.bind(this))
}) })
describe('association fetching', function() { describe('eager loading', function() {
before(function() { before(function() {
this.Task = this.sequelize.define('Task', { this.Task = this.sequelize.define('Task', { title: Sequelize.STRING })
title: Sequelize.STRING this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
})
this.User = this.sequelize.define('UserWithName', {
name: Sequelize.STRING
})
}) })
describe('1:1 associations', function() { describe('=>belongsTo only', function() {
it('fetches associated objects (1st direction)', function(done) { before(function(done) {
this.User.hasOne(this.Task) this.Task.belongsTo(this.Worker)
this.Task.belongsTo(this.User)
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).complete(function() {
this.User.create({ name: 'barfooz' }).success(function(user) { this.Worker.create({ name: 'worker' }).success(function(worker) {
this.Task.create({ title: 'task' }).success(function(task) { this.Task.create({ title: 'homework' }).success(function(task) {
user.setTask(task).success(function() { this.worker = worker
this.User.find({ this.task = task
where: { 'UserWithNames.id': 1 },
include: [ 'Task' ]
}).success(function(user) {
expect(user.task).toBeDefined()
expect(user.task.id).toEqual(task.id)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches no associated object if none is set (1st direction)', function(done) { this.task.setWorker(this.worker).success(done)
this.User.hasOne(this.Task) }.bind(this))
this.Task.belongsTo(this.User) }.bind(this))
}.bind(this))
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.Task.create({ title: 'task' }).success(function(task) {
this.User.find({
where: { 'UserWithNames.id': 1 },
include: [ 'Task' ]
}).success(function(user) {
expect(user.task).toEqual(null)
done()
})
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
}) })
it('fetches associated objects via "as" param (1st direction)', function(done) { it('throws an error about unexpected input if include contains a non-object', function() {
this.User.hasOne(this.Task, { as: 'Homework' }) expect(function() {
this.Task.belongsTo(this.User) this.Worker.find({ include: [ 1 ] })
}.bind(this)).toThrow()
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.Task.create({ title: 'task' }).success(function(task) {
user.setHomework(task).success(function() {
this.User.find({
where: { 'UserWithNames.id': 1 },
include: [ 'Homework' ]
}).success(function(user) {
expect(user.homework).toBeDefined()
expect(user.homework.id).toEqual(task.id)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
}) })
it('fetches associated object (2nd direction)', function(done) { it('throws an error about missing attributes if include contains an object with daoFactory', function() {
this.User.hasOne(this.Task) expect(function() {
this.Task.belongsTo(this.User) this.Worker.find({ include: [ { daoFactory: this.Worker } ] })
}.bind(this)).toThrow()
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.User.create({ name: 'another user' }).success(function(another_user) {
this.Task.create({ title: 'task' }).success(function(task) {
user.setTask(task).success(function() {
this.Task.find({
where: { 'Tasks.id': 1 },
include: [ 'UserWithName' ]
}).success(function(task) {
expect(task.userWithName).toBeDefined()
expect(task.userWithName.id).toEqual(user.id)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
}) })
it('fetches no associated object if none is set (2nd direction)', function(done) { it('throws an error if included DaoFactory is not associated', function() {
this.User.hasOne(this.Task) expect(function() {
this.Task.belongsTo(this.User) this.Worker.find({ include: [ this.Task ] })
}.bind(this)).toThrow()
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.User.create({ name: 'another user' }).success(function(another_user) {
this.Task.create({ title: 'task' }).success(function(task) {
this.Task.find({
where: { 'Tasks.id': 1 },
include: [ 'UserWithName' ]
}).success(function(task) {
expect(task.userWithName).toEqual(null)
done()
})
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
}) })
it('fetches associated object via "as" param (2nd direction)', function(done) { it('returns the associated worker via task.worker', function(done) {
this.User.hasOne(this.Task) this.Task.find({
this.Task.belongsTo(this.User, { as: 'Owner' }) where: { id: this.task.id },
include: [ this.Worker ]
this.sequelize.sync({ force: true }).success(function() { }).complete(function(err, task) {
this.User.create({ name: 'barfooz' }).success(function(user) { expect(err).toBeNull()
this.User.create({ name: 'another user' }).success(function(another_user) { expect(task).toBeDefined()
this.Task.create({ title: 'task' }).success(function(task) { expect(task.worker).toBeDefined()
user.setTask(task).success(function() { expect(task.worker.name).toEqual('worker')
this.Task.find({ done()
where: { 'Tasks.id': 1 }, }.bind(this))
include: [ 'Owner' ]
}).success(function(task) {
expect(task.owner).toBeDefined()
expect(task.owner.id).toEqual(user.id)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
}) })
}) })
it('fetches associated objects for 1:N associations (1st direction)', function(done) { describe('=>hasOne only', function() {
this.User.hasMany(this.Task) before(function(done) {
this.Task.belongsTo(this.User) this.Worker.hasOne(this.Task)
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).complete(function() {
this.User.create({ name: 'barfooz' }).success(function(user) { this.Worker.create({ name: 'worker' }).success(function(worker) {
this.Task.create({ title: 'task1' }).success(function(task1) { this.Task.create({ title: 'homework' }).success(function(task) {
this.Task.create({ title: 'task2' }).success(function(task2) { this.worker = worker
user.setTasks([task1, task2]).success(function() { this.task = task
this.User.find({
where: { 'UserWithNames.id': 1 },
include: [ 'Task' ]
}).success(function(user) {
expect(user.tasks).toBeDefined()
expect(
user.tasks.map(function(t) { return t.id })
).toEqual(
[ task1.id, task2.id ]
)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches associated objects via "as" param for 1:N associations (1st direction)', function(done) {
this.User.hasMany(this.Task, { as: 'Homeworks' })
this.Task.belongsTo(this.User)
this.sequelize.sync({ force: true }).success(function() { this.worker.setTask(this.task).success(done)
this.User.create({ name: 'barfooz' }).success(function(user) { }.bind(this))
this.Task.create({ title: 'task1' }).success(function(task1) { }.bind(this))
this.Task.create({ title: 'task2' }).success(function(task2) { }.bind(this))
user.setHomeworks([task1, task2]).success(function() { })
this.User.find({
where: { 'UserWithNames.id': 1 },
include: [ 'Homeworks' ]
}).success(function(user) {
expect(user.homeworks).toBeDefined()
expect(
user.homeworks.map(function(t) { return t.id })
).toEqual(
[ task1.id, task2.id ]
)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches no associated objects for 1:N associations if none are set (1st direction)', function(done) {
this.User.hasMany(this.Task)
this.Task.belongsTo(this.User)
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.Task.create({ title: 'task1' }).success(function(task1) {
this.User.find({
where: { 'UserWithNames.id': 1 },
include: [ 'Task' ]
}).success(function(user) {
expect(user.tasks.length).toEqual(0)
done()
})
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches associated objects for 1:N associations (2nd direction)', function(done) {
this.User.hasMany(this.Task)
this.Task.belongsTo(this.User)
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.Task.create({ title: 'task1' }).success(function(task1) {
this.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).success(function() {
this.Task.find({
where: { 'Tasks.id': 1 },
include: [ 'UserWithName' ]
}).success(function(task) {
expect(task.userWithName).toBeDefined()
expect(task.userWithName.name).toEqual(user.name)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches associated objects via "as" param for 1:N associations (2nd direction)', function(done) {
this.User.hasMany(this.Task)
this.Task.belongsTo(this.User, { as: 'Owner'})
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user) {
this.Task.create({ title: 'task1' }).success(function(task1) {
this.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).success(function() {
this.Task.find({
where: { 'Tasks.id': 1 },
include: [ 'Owner' ]
}).success(function(task) {
expect(task.owner).toBeDefined()
expect(task.owner.name).toEqual(user.name)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches associated objects for N:M associations (1st direction)', function(done) {
this.User.hasMany(this.Task)
this.Task.hasMany(this.User)
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user1) {
this.Task.create({ title: 'task1' }).success(function(task1) {
this.Task.create({ title: 'task2' }).success(function(task2) {
user1.setTasks([task1, task2]).success(function() {
this.User.find({
where: { 'UserWithNames.id': user1.id },
include: [ 'Task' ]
}).success(function(user) {
expect(user.tasks).toBeDefined()
expect(
user.tasks.map(function(t) { return t.id })
).toEqual(
[ task1.id, task2.id ]
)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches no associated objects for N:M associations if none are set (1st direction)', function(done) {
this.User.hasMany(this.Task)
this.Task.hasMany(this.User)
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user1) {
this.Task.create({ title: 'task1' }).success(function(task1) {
this.Task.create({ title: 'task2' }).success(function(task2) {
this.User.find({
where: { 'UserWithNames.id': user1.id },
include: [ 'Task' ]
}).success(function(user) {
expect(user.tasks.length).toEqual(0)
done()
})
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches associated objects via "as" param for N:M associations (1st direction)', function(done) {
this.User.hasMany(this.Task, { as: 'Homeworks' })
this.Task.hasMany(this.User, { as: 'Owners' })
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user1) {
this.Task.create({ title: 'task1' }).success(function(task1) { it('throws an error if included DaoFactory is not associated', function() {
this.Task.create({ title: 'task2' }).success(function(task2) { expect(function() {
user1.setHomeworks([task1, task2]).success(function() { this.Task.find({ include: [ this.Worker ] })
this.User.find({ }.bind(this)).toThrow()
where: { 'UserWithNames.id': user1.id }, })
include: [ 'Homeworks' ]
}).success(function(user) {
expect(user.homeworks).toBeDefined()
expect(
user.homeworks.map(function(t) { return t.id })
).toEqual(
[ task1.id, task2.id ]
)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create it('returns the associated task via worker.task', function(done) {
}.bind(this)) //- sequelize.sync this.Worker.find({
where: { id: this.worker.id },
include: [ this.Task ]
}).complete(function(err, worker) {
expect(err).toBeNull()
expect(worker).toBeDefined()
expect(worker.task).toBeDefined()
expect(worker.task.title).toEqual('homework')
done()
}.bind(this))
})
}) })
it('fetches associated objects for N:M associations (2nd direction)', function(done) { describe('=>hasMany only', function() {
this.User.hasMany(this.Task) before(function(done) {
this.Task.hasMany(this.User) this.Worker.hasMany(this.Task)
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).complete(function() {
this.User.create({ name: 'barfooz' }).success(function(user1) { this.Worker.create({ name: 'worker' }).success(function(worker) {
this.Task.create({ title: 'homework' }).success(function(task) {
this.worker = worker
this.task = task
this.Task.create({ title: 'task1' }).success(function(task1) { this.worker.setTasks([ this.task ]).success(done)
this.Task.create({ title: 'task2' }).success(function(task2) { }.bind(this))
user1.setTasks([task1, task2]).success(function() { }.bind(this))
this.Task.find({ }.bind(this))
where: { 'Tasks.id': task1.id }, })
include: [ 'UserWithName' ]
}).success(function(task) {
expect(task.userWithNames).toBeDefined()
expect(
task.userWithNames.map(function(u) { return u.id })
).toEqual(
[ user1.id ]
)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create
}.bind(this)) //- sequelize.sync
})
it('fetches associated objects via "as" param for N:M associations (2nd direction)', function(done) {
this.User.hasMany(this.Task, { as: 'Homeworks' })
this.Task.hasMany(this.User, { as: 'Owners' })
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user1) {
this.Task.create({ title: 'task1' }).success(function(task1) { it('throws an error if included DaoFactory is not associated', function() {
this.Task.create({ title: 'task2' }).success(function(task2) { expect(function() {
user1.setHomeworks([task1, task2]).success(function() { this.Task.find({ include: [ this.Worker ] })
this.Task.find({ }.bind(this)).toThrow()
where: { 'Tasks.id': task1.id }, })
include: [ 'Owners' ]
}).success(function(task) {
expect(task.owners).toBeDefined()
expect(
task.owners.map(function(u) { return u.id })
).toEqual(
[ user1.id ]
)
done()
})
}.bind(this)) //- setTask
}.bind(this)) //- Task.create
}.bind(this)) //- Task.create
}.bind(this)) //- User.create it('returns the associated tasks via worker.tasks', function(done) {
}.bind(this)) //- sequelize.sync this.Worker.find({
where: { id: this.worker.id },
include: [ this.Task ]
}).complete(function(err, worker) {
expect(err).toBeNull()
expect(worker).toBeDefined()
expect(worker.tasks).toBeDefined()
expect(worker.tasks[0].title).toEqual('homework')
done()
}.bind(this))
})
}) })
}) })
// describe('association fetching', function() {
// before(function() {
// this.Task = this.sequelize.define('Task', {
// title: Sequelize.STRING
// })
// this.User = this.sequelize.define('UserWithName', {
// name: Sequelize.STRING
// })
// })
// describe('1:1 associations', function() {
// it('fetches associated objects (1st direction)', function(done) {
// this.User.hasOne(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task' }).success(function(task) {
// user.setTask(task).success(function() {
// this.User.find({
// where: { 'UserWithNames.id': 1 },
// include: [ 'Task' ]
// }).success(function(user) {
// expect(user.task).toBeDefined()
// expect(user.task.id).toEqual(task.id)
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches no associated object if none is set (1st direction)', function(done) {
// this.User.hasOne(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task' }).success(function(task) {
// this.User.find({
// where: { 'UserWithNames.id': 1 },
// include: [ 'Task' ]
// }).success(function(user) {
// expect(user.task).toEqual(null)
// done()
// })
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects via "as" param (1st direction)', function(done) {
// this.User.hasOne(this.Task, { as: 'Homework' })
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task' }).success(function(task) {
// user.setHomework(task).success(function() {
// this.User.find({
// where: { 'UserWithNames.id': 1 },
// include: [ 'Homework' ]
// }).success(function(user) {
// expect(user.homework).toBeDefined()
// expect(user.homework.id).toEqual(task.id)
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated object (2nd direction)', function(done) {
// this.User.hasOne(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.User.create({ name: 'another user' }).success(function(another_user) {
// this.Task.create({ title: 'task' }).success(function(task) {
// user.setTask(task).success(function() {
// this.Task.find({
// where: { 'Tasks.id': 1 },
// include: [ 'UserWithName' ]
// }).success(function(task) {
// expect(task.userWithName).toBeDefined()
// expect(task.userWithName.id).toEqual(user.id)
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches no associated object if none is set (2nd direction)', function(done) {
// this.User.hasOne(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.User.create({ name: 'another user' }).success(function(another_user) {
// this.Task.create({ title: 'task' }).success(function(task) {
// this.Task.find({
// where: { 'Tasks.id': 1 },
// include: [ 'UserWithName' ]
// }).success(function(task) {
// expect(task.userWithName).toEqual(null)
// done()
// })
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated object via "as" param (2nd direction)', function(done) {
// this.User.hasOne(this.Task)
// this.Task.belongsTo(this.User, { as: 'Owner' })
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.User.create({ name: 'another user' }).success(function(another_user) {
// this.Task.create({ title: 'task' }).success(function(task) {
// user.setTask(task).success(function() {
// this.Task.find({
// where: { 'Tasks.id': 1 },
// include: [ 'Owner' ]
// }).success(function(task) {
// expect(task.owner).toBeDefined()
// expect(task.owner.id).toEqual(user.id)
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// })
// it('fetches associated objects for 1:N associations (1st direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user.setTasks([task1, task2]).success(function() {
// this.User.find({
// where: { 'UserWithNames.id': 1 },
// include: [ 'Task' ]
// }).success(function(user) {
// expect(user.tasks).toBeDefined()
// expect(
// user.tasks.map(function(t) { return t.id })
// ).toEqual(
// [ task1.id, task2.id ]
// )
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects via "as" param for 1:N associations (1st direction)', function(done) {
// this.User.hasMany(this.Task, { as: 'Homeworks' })
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user.setHomeworks([task1, task2]).success(function() {
// this.User.find({
// where: { 'UserWithNames.id': 1 },
// include: [ 'Homeworks' ]
// }).success(function(user) {
// expect(user.homeworks).toBeDefined()
// expect(
// user.homeworks.map(function(t) { return t.id })
// ).toEqual(
// [ task1.id, task2.id ]
// )
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches no associated objects for 1:N associations if none are set (1st direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.User.find({
// where: { 'UserWithNames.id': 1 },
// include: [ 'Task' ]
// }).success(function(user) {
// expect(user.tasks.length).toEqual(0)
// done()
// })
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects for 1:N associations (2nd direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.belongsTo(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user.setTasks([task1, task2]).success(function() {
// this.Task.find({
// where: { 'Tasks.id': 1 },
// include: [ 'UserWithName' ]
// }).success(function(task) {
// expect(task.userWithName).toBeDefined()
// expect(task.userWithName.name).toEqual(user.name)
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects via "as" param for 1:N associations (2nd direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.belongsTo(this.User, { as: 'Owner'})
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user.setTasks([task1, task2]).success(function() {
// this.Task.find({
// where: { 'Tasks.id': 1 },
// include: [ 'Owner' ]
// }).success(function(task) {
// expect(task.owner).toBeDefined()
// expect(task.owner.name).toEqual(user.name)
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects for N:M associations (1st direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.hasMany(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user1) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user1.setTasks([task1, task2]).success(function() {
// this.User.find({
// where: { 'UserWithNames.id': user1.id },
// include: [ 'Task' ]
// }).success(function(user) {
// expect(user.tasks).toBeDefined()
// expect(
// user.tasks.map(function(t) { return t.id })
// ).toEqual(
// [ task1.id, task2.id ]
// )
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches no associated objects for N:M associations if none are set (1st direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.hasMany(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user1) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// this.User.find({
// where: { 'UserWithNames.id': user1.id },
// include: [ 'Task' ]
// }).success(function(user) {
// expect(user.tasks.length).toEqual(0)
// done()
// })
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects via "as" param for N:M associations (1st direction)', function(done) {
// this.User.hasMany(this.Task, { as: 'Homeworks' })
// this.Task.hasMany(this.User, { as: 'Owners' })
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user1) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user1.setHomeworks([task1, task2]).success(function() {
// this.User.find({
// where: { 'UserWithNames.id': user1.id },
// include: [ 'Homeworks' ]
// }).success(function(user) {
// expect(user.homeworks).toBeDefined()
// expect(
// user.homeworks.map(function(t) { return t.id })
// ).toEqual(
// [ task1.id, task2.id ]
// )
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects for N:M associations (2nd direction)', function(done) {
// this.User.hasMany(this.Task)
// this.Task.hasMany(this.User)
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user1) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user1.setTasks([task1, task2]).success(function() {
// this.Task.find({
// where: { 'Tasks.id': task1.id },
// include: [ 'UserWithName' ]
// }).success(function(task) {
// expect(task.userWithNames).toBeDefined()
// expect(
// task.userWithNames.map(function(u) { return u.id })
// ).toEqual(
// [ user1.id ]
// )
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// it('fetches associated objects via "as" param for N:M associations (2nd direction)', function(done) {
// this.User.hasMany(this.Task, { as: 'Homeworks' })
// this.Task.hasMany(this.User, { as: 'Owners' })
// this.sequelize.sync({ force: true }).success(function() {
// this.User.create({ name: 'barfooz' }).success(function(user1) {
// this.Task.create({ title: 'task1' }).success(function(task1) {
// this.Task.create({ title: 'task2' }).success(function(task2) {
// user1.setHomeworks([task1, task2]).success(function() {
// this.Task.find({
// where: { 'Tasks.id': task1.id },
// include: [ 'Owners' ]
// }).success(function(task) {
// expect(task.owners).toBeDefined()
// expect(
// task.owners.map(function(u) { return u.id })
// ).toEqual(
// [ user1.id ]
// )
// done()
// })
// }.bind(this)) //- setTask
// }.bind(this)) //- Task.create
// }.bind(this)) //- Task.create
// }.bind(this)) //- User.create
// }.bind(this)) //- sequelize.sync
// })
// })
}) //- describe: find }) //- describe: find
describe('findAll', function findAll() { describe('findAll', function findAll() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!