Skip to content

Commit

Permalink
fix(record_api): Improves url building and adds support for falsy $pks
Browse files Browse the repository at this point in the history
Makes the scope's `$urlFor` method look for a `$buildUrl` method in the
scoped resource, if available, then url building responsability is
given to the resource.

Fixes #205
  • Loading branch information
iobaixas committed Nov 26, 2014
1 parent 5fcdfe6 commit db4e63b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 15 deletions.
40 changes: 27 additions & 13 deletions src/module/api/record-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@ RMModule.factory('RMRecordApi', ['RMUtils', function(Utils) {
};

RelationScope.prototype = {
// record url is nested only for nested resources
$urlFor: function(_resource) {
if(_resource.$isCollection) return Utils.joinUrl(this.$scope.$url(), this.$partial);

if(this.$target.isNested()) {
return this.$fetchUrlFor();
$nestedUrl: function() {
return Utils.joinUrl(this.$scope.$url(), this.$partial);
},

// url is nested for collections and nested records
$urlFor: function(_resource) {
if(_resource.$isCollection || this.$target.isNested()) {
return this.$nestedUrl();
} else {
return this.$target.$urlFor(_resource);
}
},

// fetch url is always nested
// a record's fetch url is always nested
$fetchUrlFor: function(/* _resource */) {
return Utils.joinUrl(this.$scope.$url(), this.$partial);
return this.$nestedUrl();
},

// create is not posible in nested members
Expand Down Expand Up @@ -111,6 +114,19 @@ RMModule.factory('RMRecordApi', ['RMUtils', function(Utils) {
this.$dispatch('after-init');
},

/**
* @memberof RecordApi#
*
* @description Called the resource's scope $urlFor method to build the url for the record using the proper scope.
*
* By default the resource partial url is just its `$pk` property. This can be overriden to provide other routing approaches.
*
* @return {string} The resource partial url
*/
$buildUrl: function(_scope) {
return (this.$pk === undefined || this.$pk === null) ? null : Utils.joinUrl(_scope.$url(), this.$pk + '');
},

/**
* @memberof RecordApi#
*
Expand Down Expand Up @@ -163,7 +179,7 @@ RMModule.factory('RMRecordApi', ['RMUtils', function(Utils) {
$decode: function(_raw, _mask) {
// IDEA: let user override serializer
this.$type.decode(this, _raw, _mask || Utils.READ_MASK);
if(!this.$pk) this.$pk = this.$type.inferKey(_raw); // TODO: warn if key changes
if(this.$pk === undefined || this.$pk === null) this.$pk = this.$type.inferKey(_raw); // TODO: warn if key changes
this.$dispatch('after-feed', [_raw]);
return this;
},
Expand Down Expand Up @@ -335,11 +351,9 @@ RMModule.factory('RMRecordApi', ['RMUtils', function(Utils) {
*/
$destroy: function() {
return this.$action(function() {
if(this.$pk)
var url = this.$url('destroy');
if(url)
{
var url = this.$url('destroy');
Utils.assert(!!url, 'Cant $destroy if resource is not bound');

var request = { method: 'DELETE', url: url };

this
Expand All @@ -358,7 +372,7 @@ RMModule.factory('RMRecordApi', ['RMUtils', function(Utils) {
}
else
{
// If not yet identified, just remove from scope
// If not yet bound, just remove from parent
if(this.$scope.$remove) this.$scope.$remove(this);
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/module/api/scope-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ RMModule.factory('RMScopeApi', ['RMUtils', function(Utils) {
*/
$urlFor: function(_resource) {
// force item unscoping if model is not nested (maybe make this optional)
var baseUrl = this.$type.$url() || this.$url();
return _resource.$isCollection ? baseUrl : Utils.joinUrl(baseUrl, _resource.$pk);
var scope = this.$type.isNested() ? this : this.$type;
return typeof _resource.$buildUrl === 'function' ? _resource.$buildUrl(scope) : scope.$url();
},

/**
Expand Down
6 changes: 6 additions & 0 deletions test/scope-api-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ describe('Restmod scope api:', function() {
Bike = restmod.model('/api/bikes');
}));

describe('$urlFor', function() {
it('return a valid url if resource $pk is 0', function() {
expect(Bike.$urlFor(Bike.$new(0))).not.toBeNull();
});
});

describe('$collection', function() {
// TODO.
});
Expand Down

0 comments on commit db4e63b

Please sign in to comment.