From 9ac4d7deb4b0436af7ce29ed3f4b95128f49b99e Mon Sep 17 00:00:00 2001 From: Partap Davis Date: Tue, 17 Feb 2015 22:04:31 -0700 Subject: [PATCH] Promisify model relation methods When a callback is omitted from a method on a model relation that supports promises, return that promise. This includes all the standard DAO methods, as well as any user-defined methods that return promises. e.g.: mylist.todos.create({name: 'Item 1'}) // returns Promise This API will use native ES6 promises if available. If not available, or to force the use of another Promise library, you must assign the global.Promise object. e.g.: global.Promise = require('bluebird') Relations affected: - BelongsTo - HasOne - HasMany - HasManyThrough - HasAndBelongsToMany - ReferencesMany - EmbedsOne Exceptions: The EmbedsMany relation has not been promisified, because most of the methods return synchronous values. The base relation getter method [e.g.: mylist.todos()] has not been promisified, due to its default caching behavior. New Methods: - getAsync(condition, cb) A new method "getAsync()" has been added to all relations except EmbedsMany, which always fetches from the datasource rather than from the cache. It takes an optional "where" condition (except for HasOne and BelongsTo) and an optional callback. If the callback is omitted, a Promise is returned. --- test/relations.test.js | 74 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/test/relations.test.js b/test/relations.test.js index 91b78ffc0..44ecd409f 100644 --- a/test/relations.test.js +++ b/test/relations.test.js @@ -208,6 +208,37 @@ describe('relations', function () { } }); + it('should fetch all scoped instances with getAsync with callback', function (done) { + Book.create(function (err, book) { + book.chapters.create({name: 'a'}, function () { + book.chapters.create({name: 'z'}, function () { + book.chapters.create({name: 'c'}, function () { + verify(book); + }); + }); + }); + }); + function verify(book) { + book.chapters(function (err, ch) { + should.not.exist(err); + should.exist(ch); + ch.should.have.lengthOf(3); + + var chapters = book.chapters(); + chapters.should.eql(ch); + + book.chapters.getAsync({order: 'name DESC'}, function (e, c) { + should.not.exist(e); + should.exist(c); + + c.shift().name.should.equal('z'); + c.pop().name.should.equal('a'); + done(); + }); + }); + } + }); + it('should find scoped record', function (done) { var id; Book.create(function (err, book) { @@ -2238,6 +2269,28 @@ describe('relations', function () { }); }); + it('can be used to query data with getAsync with callback', function (done) { + List.hasMany('todos', {model: Item}); + db.automigrate(function () { + List.create({name: 'List 1'}, function (e, list) { + listId = list.id; + should.not.exist(e); + should.exist(list); + list.todos.create({name: 'Item 1'},function (err, todo) { + itemId = todo.id; + todo.list.getAsync(function (e, l) { + should.not.exist(e); + should.exist(l); + l.should.be.an.instanceOf(List); + todo.list().id.should.equal(l.id); + todo.list().name.should.equal('List 1'); + done(); + }); + }); + }); + }); + }); + it('can be used to query data with promises', function (done) { List.hasMany('todos', {model: Item}); db.automigrate(function () { @@ -2542,6 +2595,27 @@ describe('relations', function () { }); }); + it('can be used to query data with getAsync with callback', function (done) { + db.automigrate(function () { + Supplier.create({name: 'Supplier 1'}, function (e, supplier) { + supplierId = supplier.id; + should.not.exist(e); + should.exist(supplier); + supplier.account.create({accountNo: 'a01'}, function (err, account) { + supplier.account.getAsync(function (e, act) { + accountId = act.id; + should.not.exist(e); + should.exist(act); + act.should.be.an.instanceOf(Account); + supplier.account().id.should.equal(act.id); + act.supplierName.should.equal(supplier.name); + done(); + }); + }); + }); + }); + }); + it('can be used to query data with promises', function (done) { db.automigrate(function () { Supplier.create({name: 'Supplier 1'})