refactor: deduce scope path prefix in adapter rather than passing it via the model save method
This commit is contained in:
3 files changed
+29
-41
No files matched your search
@@ -59,8 +59,13 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Prepends a scope to the URL prefix, if a scope is passed via the
|
||||
* snapshot's `adapterOptions.scopeID` field.
|
||||
* Prepends a scope to the URL prefix. Precedence is given to the ID passed
|
||||
* via `adapterOptions.scopeID`. If this value isn't found in
|
||||
* `adapterOptions`, we look to the `scope.scope_id` field on the snapshot,
|
||||
* which most resources have.
|
||||
*
|
||||
* Note: scopes themselves never receive a scope URL prefix.
|
||||
*
|
||||
* @override
|
||||
* @param {string} path
|
||||
* @param {string} parentURL
|
||||
@@ -69,18 +74,27 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
* @param {object} snapshot
|
||||
* @return {string}
|
||||
*/
|
||||
urlPrefix(path, parentURL, modelName, id, snapshot={}) {
|
||||
urlPrefix(path, parentURL, modelName, id, snapshot) {
|
||||
const prefix = super.urlPrefix(...arguments);
|
||||
const isScope = modelName === 'scope';
|
||||
let scopePath = '';
|
||||
let scopeID = '';
|
||||
if (snapshot) {
|
||||
// Not all snapshots have `attr` (such as array snapshots),
|
||||
// so we do this sort of ugly check.
|
||||
if (snapshot.attr) {
|
||||
const parentScope = snapshot.attr('scope');
|
||||
if (parentScope) scopeID = parentScope.attr('scope_id');
|
||||
}
|
||||
// Attempt to get scopeID from adapterOptions and fallback on its current
|
||||
// value if it wasn't passed through options.
|
||||
scopeID = getWithDefault(snapshot, 'adapterOptions.scopeID', scopeID);
|
||||
}
|
||||
// Only non-scope resources need a scope path, since scope resources
|
||||
// aren't technically "scoped" the same way.
|
||||
if (!isScope) {
|
||||
scopePath = getWithDefault(snapshot, 'adapterOptions.scopeID', '');
|
||||
// Ensure a slash is added between prefix + scope path if needed.
|
||||
if (scopePath && prefix.charAt(prefix.length - 1) !== '/') {
|
||||
scopePath = `/scopes/${scopePath}`;
|
||||
}
|
||||
// Ensure a slash is added between prefix + scope path if needed.
|
||||
if (!isScope && scopeID && prefix.charAt(prefix.length - 1) !== '/') {
|
||||
scopePath = `/scopes/${scopeID}`;
|
||||
}
|
||||
return `${prefix}${scopePath}`;
|
||||
}
|
||||
|
||||
@@ -84,32 +84,4 @@ export default class BaseModel extends Model {
|
||||
return !this.canSave;
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* If this model instance has a related scope, the scope's ID will be passed
|
||||
* via `adapterOptions.scopeID` automatically. End users may optionally
|
||||
* pass a custom scope ID to override.
|
||||
*
|
||||
* @example
|
||||
* model.save(); // passes the model's current scope ID
|
||||
* model.save({adapterOptions: {scopeID: 'global'}}); // override scope ID
|
||||
*
|
||||
* End users may specify a _custom method_ via `adapterOptions.method`.
|
||||
* Custom methods are appended to the record's URL by the adapter.
|
||||
*
|
||||
* @example
|
||||
* // Results in a URL: `/v1/model-name/id:my-custom-method`
|
||||
* model.save({adapterOptions: {method: 'my-custom-method'}});
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
save(options={adapterOptions: {}}) {
|
||||
const scopeID = this.scopeID;
|
||||
if (scopeID && !options.adapterOptions.scopeID) {
|
||||
options.adapterOptions.scopeID = scopeID;
|
||||
}
|
||||
return super.save(options);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,7 +29,7 @@ module('Unit | Adapter | application', function (hooks) {
|
||||
const scopeID = 'global';
|
||||
const adapter = this.owner.lookup('adapter:application');
|
||||
const prefix = adapter.urlPrefix(null, null, null, null, {
|
||||
adapterOptions: {scopeID}
|
||||
adapterOptions: { scopeID }
|
||||
});
|
||||
assert.ok(config.api.namespace);
|
||||
assert.equal(prefix, `v1/scopes/${scopeID}`);
|
||||
@@ -40,7 +40,7 @@ module('Unit | Adapter | application', function (hooks) {
|
||||
const scopeID = 'global';
|
||||
const adapter = this.owner.lookup('adapter:application');
|
||||
const prefix = adapter.urlPrefix(null, null, 'scope', null, {
|
||||
adapterOptions: {scopeID}
|
||||
adapterOptions: { scopeID }
|
||||
});
|
||||
assert.equal(prefix, `v1`);
|
||||
});
|
||||
@@ -56,7 +56,7 @@ module('Unit | Adapter | application', function (hooks) {
|
||||
const method = 'set-something';
|
||||
const adapter = this.owner.lookup('adapter:application');
|
||||
const suffix = adapter.urlSuffix(null, null, {
|
||||
adapterOptions: {method}
|
||||
adapterOptions: { method }
|
||||
});
|
||||
assert.ok(config.api.namespace);
|
||||
assert.equal(suffix, ':set-something');
|
||||
@@ -95,7 +95,9 @@ module('Unit | Adapter | application', function (hooks) {
|
||||
assert.ok(true, 'Scoped resource URL was requested.');
|
||||
return {items: []};
|
||||
});
|
||||
await store.findAll('group', {adapterOptions: {scopeID: 'p_456'}});
|
||||
await store.findAll('group', {
|
||||
adapterOptions: { scopeID: 'p_456' }
|
||||
});
|
||||
});
|
||||
|
||||
test('it rewrites PUT to PATCH, but leaves others unchanged', function (assert) {
|
||||
|
||||
Reference in new issue
Block a user