chore: add scope conveniences
This commit is contained in:
4 files changed
+907
-7
No files matched your search
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in new issue
Block a user