diff --git a/3.0-RELEASE-NOTES.md b/3.0-RELEASE-NOTES.md index 61e33c506..aae0be658 100644 --- a/3.0-RELEASE-NOTES.md +++ b/3.0-RELEASE-NOTES.md @@ -49,3 +49,14 @@ without any callback, a promise is returned. See [pull request 918](https://github.com/strongloop/loopback-datasource-juggler/pull/918) for more details. + +## Disallow array input for updateOrCreate function + +Allowing updateOrCreate to accept an array as input would only work when +creating new model instances (not updating them), so this support has been +removed. Please use `create` function instead (array inputs only worked to +create new instances with this method before). If you would like to perform a +bulk `updateOrCreate`, you could use `async.each` or `Promise.all` to +repeatedly call `updateOfCreate` for each instance. + +Please see [Related code change](https://github.com/strongloop/loopback-datasource-juggler/pull/889) here. diff --git a/lib/dao.js b/lib/dao.js index a67957dde..1221b2c10 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -465,6 +465,11 @@ DataAccessObject.upsert = function(data, options, cb) { assert(typeof options === 'object', 'The options argument must be an object'); assert(typeof cb === 'function', 'The cb argument must be a function'); + if (Array.isArray(data)) { + cb(new Error('updateOrCreate does not support bulk mode or any array input')); + return cb.promise; + } + var hookState = {}; var self = this; diff --git a/test/manipulation.test.js b/test/manipulation.test.js index 3317a3b8c..a641cd645 100644 --- a/test/manipulation.test.js +++ b/test/manipulation.test.js @@ -658,10 +658,63 @@ describe('manipulation', function() { }); describe('updateOrCreate', function() { + var db = getSchema(); + var Todo; + + before(function setUpDatabase(done) { + Todo = db.define('Todo', { + content: String, + }); + done(); + }); + beforeEach(function deleteModelsInstances(done) { + Todo.deleteAll(done); + }); + it('has an alias "patchOrCreate"', function() { StubUser.updateOrCreate.should.equal(StubUser.patchOrCreate); }); + it('creates a model when one does not exist', function(done) { + Todo.updateOrCreate({ content: 'a' }, function(err, data) { + if (err) return done(err); + + Todo.findById(data.id, function(err, todo) { + should.exist(todo); + should.exist(todo.content); + todo.content.should.equal('a'); + + done(); + }); + }); + }); + + it('updates a model if it exists', function(done) { + Todo.create({ content: 'a' }, function(err, todo) { + Todo.updateOrCreate({ id: todo.id, content: 'b' }, function(err, data) { + if (err) return done(err); + + should.exist(data); + should.exist(data.id); + data.id.should.equal(todo.id); + should.exist(data.content); + data.content.should.equal('b'); + + done(); + }); + }); + }); + + it('throws error for queries with array input', function(done) { + Todo.updateOrCreate([{ content: 'a' }], function(err, data) { + should.exist(err); + err.message.should.containEql('bulk'); + should.not.exist(data); + + done(); + }); + }); + it('should preserve properties with dynamic setters on create', function(done) { StubUser.updateOrCreate({ password: 'foo' }, function(err, created) { if (err) return done(err);