diff --git a/packages/-ember-data/tests/integration/record-data/record-data-errors-test.ts b/packages/-ember-data/tests/integration/record-data/record-data-errors-test.ts index f6f7fb261f6..99efd8256a7 100644 --- a/packages/-ember-data/tests/integration/record-data/record-data-errors-test.ts +++ b/packages/-ember-data/tests/integration/record-data/record-data-errors-test.ts @@ -26,6 +26,9 @@ class Person extends Model { } class TestRecordData implements RecordData { + id = null; + modelName = 'tst'; + commitWasRejected(recordIdentifier: RecordIdentifier, errors?: JsonApiValidationError[]): void {} // Use correct interface once imports have been fix diff --git a/packages/-ember-data/tests/integration/record-data/record-data-state-test.ts b/packages/-ember-data/tests/integration/record-data/record-data-state-test.ts index a18e5c8c314..6d9ddfcf7e4 100644 --- a/packages/-ember-data/tests/integration/record-data/record-data-state-test.ts +++ b/packages/-ember-data/tests/integration/record-data/record-data-state-test.ts @@ -24,6 +24,9 @@ class Person extends Model { } class TestRecordData implements RecordData { + id = null; + modelName = 'tst'; + commitWasRejected(): void {} // Use correct interface once imports have been fix diff --git a/packages/store/addon/-private/system/references/belongs-to.js b/packages/store/addon/-private/system/references/belongs-to.js index 3c70fd4fd5d..93b1444c2a1 100644 --- a/packages/store/addon/-private/system/references/belongs-to.js +++ b/packages/store/addon/-private/system/references/belongs-to.js @@ -7,7 +7,7 @@ import { assertPolymorphicType } from '@ember-data/store/-debug'; import recordDataFor from '../record-data-for'; import { peekRecordIdentifier } from '../store/internal-model-factory'; -import Reference from './reference'; +import Reference, { INTERNAL_MODELS } from './reference'; /** @module @ember-data/store @@ -144,7 +144,7 @@ export default class BelongsToReference extends Reference { } assertPolymorphicType( - this.internalModel, + INTERNAL_MODELS.get(this.recordData), this.belongsToRelationship.relationshipMeta, record._internalModel, this.store diff --git a/packages/store/addon/-private/system/references/has-many.js b/packages/store/addon/-private/system/references/has-many.js index 018b33abe9d..648e7e0579f 100644 --- a/packages/store/addon/-private/system/references/has-many.js +++ b/packages/store/addon/-private/system/references/has-many.js @@ -6,7 +6,7 @@ import { resolve } from 'rsvp'; import { assertPolymorphicType } from '@ember-data/store/-debug'; import recordDataFor from '../record-data-for'; -import Reference from './reference'; +import Reference, { INTERNAL_MODELS } from './reference'; /** @module @ember-data/store @@ -179,19 +179,21 @@ export default class HasManyReference extends Reference { array = payload.data; } + let internalModel = INTERNAL_MODELS.get(this.recordData); + let internalModels = array.map(obj => { let record = this.store.push(obj); if (DEBUG) { let relationshipMeta = this.hasManyRelationship.relationshipMeta; - assertPolymorphicType(this.internalModel, relationshipMeta, record._internalModel, this.store); + assertPolymorphicType(internalModel, relationshipMeta, record._internalModel, this.store); } return recordDataFor(record); }); this.hasManyRelationship.computeChanges(internalModels); - return this.internalModel.getHasMany(this.hasManyRelationship.key); + return internalModel.getHasMany(this.hasManyRelationship.key); // TODO IGOR it seems wrong that we were returning the many array here //return this.hasManyRelationship.manyArray; }); @@ -253,8 +255,9 @@ export default class HasManyReference extends Reference { @return {ManyArray} */ value() { + let internalModel = INTERNAL_MODELS.get(this.recordData); if (this._isLoaded()) { - return this.internalModel.getManyArray(this.key); + return internalModel.getManyArray(this.key); } return null; @@ -323,7 +326,8 @@ export default class HasManyReference extends Reference { this has-many relationship. */ load(options) { - return this.internalModel.getHasMany(this.key, options); + let internalModel = INTERNAL_MODELS.get(this.recordData); + return internalModel.getHasMany(this.key, options); } /** @@ -375,6 +379,7 @@ export default class HasManyReference extends Reference { @return {Promise} a promise that resolves with the ManyArray in this has-many relationship. */ reload(options) { - return this.internalModel.reloadHasMany(this.key, options); + let internalModel = INTERNAL_MODELS.get(this.recordData); + return internalModel.reloadHasMany(this.key, options); } } diff --git a/packages/store/addon/-private/system/references/record.ts b/packages/store/addon/-private/system/references/record.ts index 5b736b5a77b..6c6600ad456 100644 --- a/packages/store/addon/-private/system/references/record.ts +++ b/packages/store/addon/-private/system/references/record.ts @@ -1,6 +1,6 @@ import RSVP, { resolve } from 'rsvp'; -import Reference from './reference'; +import Reference, { INTERNAL_MODELS } from './reference'; type SingleResourceDocument = import('../../ts-interfaces/ember-data-json-api').SingleResourceDocument; type RecordInstance = import('../../ts-interfaces/record-instance').RecordInstance; @@ -17,9 +17,9 @@ type RecordInstance = import('../../ts-interfaces/record-instance').RecordInstan @extends Reference */ export default class RecordReference extends Reference { - public type = this.internalModel.modelName; + public type = this.recordData.modelName; private get _id() { - return this.internalModel.id; + return this.recordData.id; } /** @@ -124,8 +124,9 @@ export default class RecordReference extends Reference { @return {Model} the record for this RecordReference */ value() { - if (this.internalModel.hasRecord) { - return this.internalModel.getRecord(); + let internalModel = INTERNAL_MODELS.get(this.recordData); + if (internalModel && internalModel.hasRecord) { + return internalModel.getRecord(); } return null; } diff --git a/packages/store/addon/-private/system/references/reference.ts b/packages/store/addon/-private/system/references/reference.ts index a0a80015e11..1761bb6b6b6 100644 --- a/packages/store/addon/-private/system/references/reference.ts +++ b/packages/store/addon/-private/system/references/reference.ts @@ -1,3 +1,5 @@ +import { deprecate } from '@ember/debug'; + import { FULL_LINKS_ON_RELATIONSHIPS } from '@ember-data/canary-features'; import recordDataFor from '../record-data-for'; @@ -10,6 +12,7 @@ type CoreStore = import('../core-store').default; type JSONObject = import('json-typescript').Object; type JSONValue = import('json-typescript').Value; type InternalModel = import('../model/internal-model').default; +type RecordData = InternalModel['_recordData']; /** @module @ember-data/store @@ -28,6 +31,8 @@ function isResourceIdentiferWithRelatedLinks( return value && value.links && value.links.related; } +export const INTERNAL_MODELS = new WeakMap(); + /** This is the baseClass for the different References like RecordReference/HasManyReference/BelongsToReference @@ -39,12 +44,22 @@ interface Reference { } abstract class Reference { public recordData: InternalModel['_recordData']; - constructor(public store: CoreStore, public internalModel: InternalModel) { - this.recordData = recordDataFor(this); + constructor(public store: CoreStore, internalModel: InternalModel) { + this.recordData = recordDataFor(internalModel); + INTERNAL_MODELS.set(this.recordData, internalModel); } public _resource(): ResourceIdentifier | JsonApiRelationship | void {} + get internalModel() { + deprecate('Accessing the internalModel property of Reference is deprecated', false, { + id: 'ember-data:reference-internal-model', + until: '3.17', + }); + + return INTERNAL_MODELS.get(this.recordData); + } + /** This returns a string that represents how the reference will be looked up when it is loaded. If the relationship has a link it will diff --git a/packages/store/addon/-private/ts-interfaces/record-data.ts b/packages/store/addon/-private/ts-interfaces/record-data.ts index 740041b0f1b..0607c98f71f 100644 --- a/packages/store/addon/-private/ts-interfaces/record-data.ts +++ b/packages/store/addon/-private/ts-interfaces/record-data.ts @@ -13,6 +13,9 @@ export interface ChangedAttributesHash { } export interface RecordData { + id: string | null; + modelName: string; + pushData(data: JsonApiResource, calculateChange?: boolean): void; clientDidCreate(): void; willCommit(): void;