diff --git a/lib/model-builder.js b/lib/model-builder.js index a688004d..aa052dea 100644 --- a/lib/model-builder.js +++ b/lib/model-builder.js @@ -110,7 +110,10 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett var args = slice.call(arguments); var pluralName = (settings && settings.plural) || inflection.pluralize(className); - + + var httpOptions = (settings && settings.http) || {}; + var pathName = httpOptions.path || pluralName; + if (!className) { throw new Error('Class name required'); } @@ -188,7 +191,7 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett hiddenProperty(ModelClass, 'dataSource', modelBuilder); // Keep for back-compatibility hiddenProperty(ModelClass, 'pluralModelName', pluralName); hiddenProperty(ModelClass, 'relations', {}); - hiddenProperty(ModelClass, 'http', { path: '/' + pluralName }); + hiddenProperty(ModelClass, 'http', { path: '/' + pathName }); hiddenProperty(ModelClass, 'base', ModelBaseClass); // inherit ModelBaseClass static methods diff --git a/lib/relation-definition.js b/lib/relation-definition.js index 44532273..bace4705 100644 --- a/lib/relation-definition.js +++ b/lib/relation-definition.js @@ -70,11 +70,7 @@ function extendScopeMethods(definition, scopeMethods, ext) { return relationMethod.apply(relation, arguments); }; if (relationMethod.shared) { - method.shared = true; - method.accepts = relationMethod.accepts; - method.returns = relationMethod.returns; - method.http = relationMethod.http; - method.description = relationMethod.description; + sharedMethod(definition, key, method, relationMethod); } customMethods.push(key); } @@ -573,15 +569,19 @@ function scopeMethod(definition, methodName) { var relationMethod = relationClass.prototype[methodName]; if (relationMethod.shared) { - method.shared = true; - method.accepts = relationMethod.accepts; - method.returns = relationMethod.returns; - method.http = relationMethod.http; - method.description = relationMethod.description; + sharedMethod(definition, methodName, method, relationMethod); } return method; } +function sharedMethod(definition, methodName, method, relationMethod) { + method.shared = true; + method.accepts = relationMethod.accepts; + method.returns = relationMethod.returns; + method.http = relationMethod.http; + method.description = relationMethod.description; +}; + /** * Find a related item by foreign key * @param {*} fkId The foreign key @@ -1295,6 +1295,15 @@ RelationDefinition.hasOne = function (modelFrom, modelTo, params) { return relationMethod; } }); + + // FIXME: [rfeng] Wrap the property into a function for remoting + // so that it can be accessed as /api/// + // For example, /api/orders/1/customer + var fn = function() { + var f = this[relationName]; + f.apply(this, arguments); + }; + modelFrom.prototype['__get__' + relationName] = fn; }; /** diff --git a/test/loopback-dl.test.js b/test/loopback-dl.test.js index a6f840c3..8a63a249 100644 --- a/test/loopback-dl.test.js +++ b/test/loopback-dl.test.js @@ -548,6 +548,15 @@ describe('DataSource define model', function () { done(); }); + + it('should allow an explicit remoting path', function () { + var ds = new DataSource('memory'); + + var User = ds.define('User', {name: String, bio: String}, { + http: { path: 'accounts' } + }); + User.http.path.should.equal('/accounts'); + }); });