From 940e11125d74fad252c7275368c2ae1983cabaad Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Mon, 14 Apr 2014 14:17:56 -0700 Subject: [PATCH] Fix save implementation for remoting connector --- lib/models/data-model.js | 60 +++++++++++++++++++++++++++++++- test/e2e/remote-connector.e2e.js | 11 ++++++ test/remote-connector.test.js | 10 ++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/lib/models/data-model.js b/lib/models/data-model.js index bb8c60cf..272d02a5 100644 --- a/lib/models/data-model.js +++ b/lib/models/data-model.js @@ -2,6 +2,7 @@ * Module Dependencies. */ var Model = require('./model'); +var DataAccess = require('loopback-datasource-juggler/lib/dao'); /** * Extends Model with basic query and CRUD support. @@ -258,7 +259,21 @@ setRemoting(DataModel.count, { */ DataModel.prototype.save = function (options, callback) { - throwNotAttached(this.constructor.modelName, 'save'); + var inst = this; + var DataModel = inst.constructor; + + if(typeof options === 'function') { + callback = options; + options = {}; + } + + // delegates directly to DataAccess + DataAccess.prototype.save.call(this, options, function(err, data) { + if(err) return callback(data); + var saved = new DataModel(data); + inst.setId(saved.getId()); + callback(null, data); + }); }; @@ -329,3 +344,46 @@ setRemoting(DataModel.prototype.updateAttributes, { DataModel.prototype.reload = function reload(callback) { throwNotAttached(this.constructor.modelName, 'reload'); }; + +/** + * Set the corret `id` property for the `DataModel`. If a `Connector` defines + * a `setId` method it will be used. Otherwise the default lookup is used. You + * should override this method to handle complex ids. + * + * @param {*} val The `id` value. Will be converted to the type the id property + * specifies. + */ + +DataModel.prototype.setId = function(val) { + var ds = this.getDataSource(); + this[this.getIdName()] = val; +} + +DataModel.prototype.getId = function() { + var data = this.toObject(); + if(!data) return; + return data[this.getIdName()]; +} + +/** + * Get the id property name of the constructor. + */ + +DataModel.prototype.getIdName = function() { + return this.constructor.getIdName(); +} + +/** + * Get the id property name + */ + +DataModel.getIdName = function() { + var Model = this; + var ds = Model.getDataSource(); + + if(ds.idName) { + return ds.idName(Model.modelName); + } else { + return 'id'; + } +} diff --git a/test/e2e/remote-connector.e2e.js b/test/e2e/remote-connector.e2e.js index c1258056..3fb806fb 100644 --- a/test/e2e/remote-connector.e2e.js +++ b/test/e2e/remote-connector.e2e.js @@ -25,4 +25,15 @@ describe('RemoteConnector', function() { done(); }); }); + + it('should be able to call save', function (done) { + var m = new TestModel({ + foo: 'bar' + }); + m.save(function(err, data) { + if(err) return done(err); + assert(m.id); + done(); + }); + }); }); diff --git a/test/remote-connector.test.js b/test/remote-connector.test.js index de996b92..2a55c02c 100644 --- a/test/remote-connector.test.js +++ b/test/remote-connector.test.js @@ -30,4 +30,14 @@ describe('RemoteConnector', function() { done(); }); }); + + it('should alow instance methods to be called remotely', function (done) { + var data = {foo: 'bar'}; + var m = new this.LocalModel(data); + m.save(function(err, result) { + if(err) return done(err); + expect(result).to.deep.equal({id: 2, foo: 'bar'}); + done(); + }); + }); });