diff --git a/packages/model/addon/-private/index.ts b/packages/model/addon/-private/index.ts index b4a458de87d..5dfe41eede7 100644 --- a/packages/model/addon/-private/index.ts +++ b/packages/model/addon/-private/index.ts @@ -3,3 +3,5 @@ export { default as belongsTo } from './belongs-to'; export { default as hasMany } from './has-many'; export { default as Model } from './model'; export { default as Errors } from './errors'; + +export { default as _modelForMixin } from './system/model-for-mixin'; diff --git a/packages/model/addon/-private/system/model-for-mixin.ts b/packages/model/addon/-private/system/model-for-mixin.ts new file mode 100644 index 00000000000..f7555bf0913 --- /dev/null +++ b/packages/model/addon/-private/system/model-for-mixin.ts @@ -0,0 +1,34 @@ +import Model from '../model'; +import { getOwner } from '@ember/application'; +type Store = import('@ember-data/store').default; + +/* + In case someone defined a relationship to a mixin, for example: + ``` + let Comment = Model.extend({ + owner: belongsTo('commentable'. { polymorphic: true }) + }); + let Commentable = Ember.Mixin.create({ + comments: hasMany('comment') + }); + ``` + we want to look up a Commentable class which has all the necessary + relationship metadata. Thus, we look up the mixin and create a mock + Model, so we can access the relationship CPs of the mixin (`comments`) + in this case + */ +export default function modelForMixin(store: Store, normalizedModelName: string): Model | null { + let owner = getOwner(store); + let MaybeMixin = owner.factoryFor(`mixin:${normalizedModelName}`); + let mixin = MaybeMixin && MaybeMixin.class; + if (mixin) { + let ModelForMixin = Model.extend(mixin); + ModelForMixin.reopenClass({ + __isMixin: true, + __mixin: mixin, + }); + //Cache the class as a model + owner.register('model:' + normalizedModelName, ModelForMixin); + } + return owner.factoryFor(`model:${normalizedModelName}`); +} diff --git a/packages/store/addon/-private/system/schema-definition-service.ts b/packages/store/addon/-private/system/schema-definition-service.ts index 808ce4e9712..1d739299bce 100644 --- a/packages/store/addon/-private/system/schema-definition-service.ts +++ b/packages/store/addon/-private/system/schema-definition-service.ts @@ -5,17 +5,20 @@ import { getOwner } from '@ember/application'; import normalizeModelName from './normalize-model-name'; import { RelationshipsSchema, AttributesSchema } from '../ts-interfaces/record-data-schemas'; import require from 'require'; -import CoreStore from './core-store'; import { HAS_MODEL_PACKAGE } from '@ember-data/private-build-infra'; type Model = import('@ember-data/model').default; - -let _Model; -function getModel() { - if (HAS_MODEL_PACKAGE) { - _Model = _Model || require('@ember-data/model').default; - } - return _Model; +type ModelForMixin = (store: Store, normalizedModelName: string) => Model | null; + +let _modelForMixin: ModelForMixin; +if (HAS_MODEL_PACKAGE) { + let _found; + _modelForMixin = function() { + if (!_found) { + _found = require('@ember-data/model/-private')._modelForMixin; + } + return _found(...arguments); + }; } export class DSModelSchemaDefinitionService { @@ -83,13 +86,13 @@ export class DSModelSchemaDefinitionService { * @param normalizedModelName already normalized modelName * @return {*} */ -export function getModelFactory(store: CoreStore, cache, normalizedModelName: string): Model | null { +export function getModelFactory(store: Store, cache, normalizedModelName: string): Model | null { let factory = cache[normalizedModelName]; if (!factory) { factory = _lookupModelFactory(store, normalizedModelName); - if (!factory) { + if (!factory && HAS_MODEL_PACKAGE) { //Support looking up mixins as base types for polymorphic relationships factory = _modelForMixin(store, normalizedModelName); } @@ -114,44 +117,8 @@ export function getModelFactory(store: CoreStore, cache, normalizedModelName: st return factory; } -export function _lookupModelFactory(store, normalizedModelName) { +export function _lookupModelFactory(store: Store, normalizedModelName: string): Model | null { let owner = getOwner(store); return owner.factoryFor(`model:${normalizedModelName}`); } - -/* - In case someone defined a relationship to a mixin, for example: - ``` - let Comment = Model.extend({ - owner: belongsTo('commentable'. { polymorphic: true }) - }); - let Commentable = Ember.Mixin.create({ - comments: hasMany('comment') - }); - ``` - we want to look up a Commentable class which has all the necessary - relationship metadata. Thus, we look up the mixin and create a mock - Model, so we can access the relationship CPs of the mixin (`comments`) - in this case - */ -export function _modelForMixin(store, normalizedModelName) { - if (HAS_MODEL_PACKAGE) { - let owner = getOwner(store); - let MaybeMixin = owner.factoryFor(`mixin:${normalizedModelName}`); - let mixin = MaybeMixin && MaybeMixin.class; - - if (mixin) { - let ModelForMixin = getModel().extend(mixin); - ModelForMixin.reopenClass({ - __isMixin: true, - __mixin: mixin, - }); - - //Cache the class as a model - owner.register('model:' + normalizedModelName, ModelForMixin); - } - - return _lookupModelFactory(store, normalizedModelName); - } -}