chore: add scope conveniences

This commit is contained in:
Randall Morey committed 2020-07-22 12:08:10 -04:00
1 parent 3d432950d6
commit fd145968e3
4 files changed
+907 -7

No files matched your search

+30
View File
@@ -3,6 +3,28 @@ import { fragment } from 'ember-data-model-fragments/attributes';
import { computed } from '@ember/object';
import { get } from '@ember/object';
/**
* Base model class provides common functionality for all models.
*
* One of the most interesting features of most resources is the
* `scope` field, which arrives from the API as an embedded JSON fragment.
* It contains information such as the parent scope ID and type. This scope ID
* is then used when generation scoped resource URLs via the
* `adapterOptions.scopeID` option (see `save` method below).
*
* For convenience, developers may interact with scope in a number of ways.
* The simplest method, when you don't care about other information, is to set
* the `scopeID`, e.g. `record.scopeID = 'o_123'`. The scope JSON fragment
* may be set directly, `record.scope = { scope_id: 'o_123' }`.
* For convenience, you may even set the scope using a `Scope` model:
* `record.scopeModel = scopeModelInstance`, which automatically converts the
* scope to a JSON fragment of the proper shape and assigns it to `scope`.
*
* A record's scope may be read in one of two ways:
*
* 1) As a JSON fragment: `record.scope`,
* 2) Or as an ID: `record.scopeID`.
*/
export default class BaseModel extends Model {
// =relationships
@@ -15,6 +37,14 @@ export default class BaseModel extends Model {
// =attributes
set scopeModel(model) {
if (model) {
const json = model.serialize();
json.scope_id = model.id;
this.scope = json;
}
}
/**
* Convenience for getting and setting the parent scope ID.
* @type {string
+4 -3
View File
@@ -24,9 +24,10 @@ export default class ScopeSerializer extends ApplicationSerializer {
* @param {Object} attribute
*/
serializeAttribute(snapshot, json, key) {
let value = super.serializeAttribute(...arguments);
if (key === 'scope' && this._canSerialize(key)) {
json.parent_scope_id = snapshot.attr('scope').attr('scope_id');
const value = super.serializeAttribute(...arguments);
const parentScope = snapshot.attr('scope');
if (key === 'scope' && this._canSerialize(key) && parentScope) {
json.parent_scope_id = parentScope.attr('scope_id');
delete json[key];
}
return value;
+12 -1
View File
@@ -13,7 +13,7 @@ module('Unit | Model | base', function (hooks) {
assert.ok(model);
});
test('it may have a scope relationship', function (assert) {
test('it may have a scope fragment', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
store.push({
@@ -39,6 +39,17 @@ module('Unit | Model | base', function (hooks) {
assert.equal(model.scope.scope_id, scope.id);
});
test('it may accept a `scopeModel` for convenience, instead of a fragment', function (assert) {
assert.expect(3);
const store = this.owner.lookup('service:store');
const scope = store.createRecord('scope', {id: 'o_1', type: 'org'});
const model = store.createRecord('user', '123abc');
assert.notEqual(model.scopeID, scope.id);
model.scopeModel = scope;
assert.equal(model.scopeID, scope.id);
assert.equal(model.scope.isOrg, true);
});
test('it has a displayName attribute', function (assert) {
assert.expect(3);
const store = this.owner.lookup('service:store');
+861 -3
View File
File diff suppressed because it is too large. Load diff