Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add relationship interfaces and deprecate bunch of cache/model methods #240

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion addon/-private/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,12 @@ export default class Cache {
}
}

/**
* @deprecated
*/
findAll(type: string, options?: object): Model[] {
deprecate(
'`Cache.findAll(type)` is deprecated, use `Cache.findRecords(type)`.'
'`Cache#findAll(type)` is deprecated, use `Cache#findRecords(type)`.'
);
return this.findRecords(type, options);
}
Expand Down
6 changes: 4 additions & 2 deletions addon/-private/fields/attr.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { computed } from '@ember/object';
import { Dict } from '@orbit/utils';

import Model from '../model';

export default function(type: string, options: Dict<unknown> = {}) {
options.type = type;

return computed({
get(key) {
get(this: Model, key) {
return this.getAttribute(key);
},
set(key, value) {
set(this: Model, key, value) {
const oldValue = this.getAttribute(key);

if (value !== oldValue) {
Expand Down
37 changes: 35 additions & 2 deletions addon/-private/fields/has-many.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
import { computed } from '@ember/object';
import { Dict } from '@orbit/utils';
import { RecordIdentity } from '@orbit/data';
import Orbit from '@orbit/core';
import { DEBUG } from '@glimmer/env';

import Model from '../model';

const { deprecate } = Orbit;

export default function(type: string, options: Dict<unknown> = {}) {
options.kind = 'hasMany';
options.type = type;

return computed({
get(key) {
return this.getRelatedRecords(key);
get(this: Model, key): Model[] {
let records = this.hasMany(key).value;

if (DEBUG) {
records = [...records];
}

const pushObject = (record: RecordIdentity) => {
deprecate(
'`HasMany#pushObject(record)` is deprecated, use `Model#hasMany(relationship).add(record)`.'
);
return this.hasMany(key).add(record);
};
const removeObject = (record: RecordIdentity) => {
deprecate(
'`HasMany#removeObject(record)` is deprecated, use `Model#hasMany(relationship).remove(record)`.'
);
return this.hasMany(key).remove(record);
};

Object.defineProperty(records, 'pushObject', { value: pushObject });
Object.defineProperty(records, 'removeObject', { value: removeObject });

if (DEBUG) {
Object.freeze(records);
}

return records;
}
})
.meta({
Expand Down
12 changes: 7 additions & 5 deletions addon/-private/fields/has-one.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { computed } from '@ember/object';
import { Dict } from '@orbit/utils';

import Model from '../model';

export default function(type: string, options: Dict<unknown> = {}) {
options.kind = 'hasOne';
options.type = type;

return computed({
get(key) {
return this.getRelatedRecord(key);
get(this: Model, key) {
return this.hasOne(key).value;
},
set(key, value) {
const oldValue = this.getRelatedRecord(key);
set(this: Model, key, value: Model | null) {
const oldValue = this.hasOne(key).value;

if (value !== oldValue) {
this.replaceRelatedRecord(key, value);
this.hasOne(key).replace(value);
}

return value;
Expand Down
6 changes: 4 additions & 2 deletions addon/-private/fields/key.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { computed } from '@ember/object';
import { Dict } from '@orbit/utils';

import Model from '../model';

export default function(options: Dict<unknown> = {}) {
options.type = 'string';

return computed({
get(name) {
get(this: Model, name) {
return this.getKey(name);
},
set(name, value) {
set(this: Model, name, value: string) {
const oldValue = this.getKey(name);

if (value !== oldValue) {
Expand Down
126 changes: 65 additions & 61 deletions addon/-private/model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import EmberObject from '@ember/object';
import Orbit from '@orbit/core';
import { Dict } from '@orbit/utils';
import {
Record,
Expand All @@ -8,22 +9,21 @@ import {
RelationshipDefinition
} from '@orbit/data';

import HasMany from './relationships/has-many';
const { deprecate } = Orbit;

import { HasOneRelation, HasManyRelation } from './relations';
import Store from './store';

export interface ModelSettings {
identity: RecordIdentity;
}

interface HasManyContract {
invalidate(): void;
}

export default class Model extends EmberObject {
identity!: RecordIdentity;

private _store?: Store;
private _relatedRecords: Dict<HasManyContract> = {};
private _hasManyRelations: Dict<HasManyRelation> = {};
private _hasOneRelations: Dict<HasOneRelation> = {};

get id(): string {
return this.identity.id;
Expand Down Expand Up @@ -56,6 +56,28 @@ export default class Model extends EmberObject {
);
}

hasMany(name: string): HasManyRelation {
let relationship = this._hasManyRelations[name];
if (!relationship) {
this._hasManyRelations[name] = relationship = new HasManyRelation(
this,
name
);
}
return relationship;
}

hasOne(name: string): HasOneRelation {
let relationship = this._hasOneRelations[name];
if (!relationship) {
this._hasOneRelations[name] = relationship = new HasOneRelation(
this,
name
);
}
return relationship;
}

getAttribute(field: string): any {
return this.store.cache.peekAttribute(this.identity, field);
}
Expand All @@ -71,87 +93,69 @@ export default class Model extends EmberObject {
);
}

getRelatedRecord(relationship: string): Record | null | undefined {
return this.store.cache.peekRelatedRecord(this.identity, relationship);
/**
* @deprecated
*/
getRelatedRecord(relationship: string): Record | null {
deprecate(
'`Model#getRelatedRecord(relationship)` is deprecated, use `Model#hasOne(relationship).value`.'
);
return this.hasOne(relationship).value;
}

/**
* @deprecated
*/
async replaceRelatedRecord(
relationship: string,
relatedRecord: Model | null,
record: RecordIdentity | null,
options?: object
): Promise<void> {
await this.store.update(
t =>
t.replaceRelatedRecord(
this.identity,
relationship,
relatedRecord ? relatedRecord.identity : null
),
options
deprecate(
'`Model#replaceRelatedRecord(relationship, record)` is deprecated, use `Model#hasOne(relationship).replace(record)`.'
);
await this.hasOne(relationship).replace(record, options);
}

getRelatedRecords(relationship: string) {
this._relatedRecords = this._relatedRecords || {};

if (!this._relatedRecords[relationship]) {
this._relatedRecords[relationship] = HasMany.create({
getContent: () =>
this.store.cache.peekRelatedRecords(this.identity, relationship),
addToContent: (record: Model): Promise<void> => {
return this.addToRelatedRecords(relationship, record);
},
removeFromContent: (record: Model): Promise<void> => {
return this.removeFromRelatedRecords(relationship, record);
}
});
}
this._relatedRecords[relationship].invalidate();

return this._relatedRecords[relationship];
}

/**
* @deprecated
*/
async addToRelatedRecords(
relationship: string,
record: Model,
record: RecordIdentity,
options?: object
): Promise<void> {
await this.store.update(
t => t.addToRelatedRecords(this.identity, relationship, record.identity),
options
deprecate(
'`Model#addToRelatedRecords(relationship, record)` is deprecated, use `Model#hasMany(relationship).add(record)`.'
);
await this.hasMany(relationship).add(record, options);
}

/**
* @deprecated
*/
async removeFromRelatedRecords(
relationship: string,
record: Model,
record: RecordIdentity,
options?: object
): Promise<void> {
await this.store.update(
t =>
t.removeFromRelatedRecords(
this.identity,
relationship,
record.identity
),
options
deprecate(
'`Model#removeFromRelatedRecords(relationship, record)` is deprecated, use `Model#hasMany(relationship).remove(record)`.'
);
await this.hasMany(relationship).remove(record, options);
}

/**
* @deprecated
*/
async replaceAttributes(
properties: Dict<unknown> = {},
options?: object
): Promise<void> {
const keys = Object.keys(properties);
await this.store
.update(
t =>
keys.map(key =>
t.replaceAttribute(this.identity, key, properties[key])
),
options
)
.then(() => this);
deprecate(
'`Model#replaceAttributes(properties)` is deprecated, use `Model#update(properties)`.'
);
await this.update(properties, options);
}

async update(
Expand All @@ -176,7 +180,7 @@ export default class Model extends EmberObject {
}
}

private get store(): Store {
get store(): Store {
if (!this._store) {
throw new Error('record has been removed from Store');
}
Expand Down
Loading