From 841fe9ccf7882ccd9da4abb05518059ecc08112a Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Mon, 25 Nov 2019 22:49:19 -0500 Subject: [PATCH 1/2] [CHORE] Move _modelForMixin to Model package --- packages/model/addon/-private/index.ts | 2 + .../addon/-private/system/model-for-mixin.ts | 34 ++++++++++++ .../system/schema-definition-service.ts | 53 +++---------------- 3 files changed, 43 insertions(+), 46 deletions(-) create mode 100644 packages/model/addon/-private/system/model-for-mixin.ts 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..3ccd5845bb4 --- /dev/null +++ b/packages/model/addon/-private/system/model-for-mixin.ts @@ -0,0 +1,34 @@ +import Model from '../model'; +import Store from '@ember-data/store'; +import { getOwner } from '@ember/application'; + +/* + 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..d9cc28d087f 100644 --- a/packages/store/addon/-private/system/schema-definition-service.ts +++ b/packages/store/addon/-private/system/schema-definition-service.ts @@ -5,17 +5,14 @@ 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; +type ModelForMixin = (store: Store, normalizedModelName: string) => Model | null; -let _Model; -function getModel() { - if (HAS_MODEL_PACKAGE) { - _Model = _Model || require('@ember-data/model').default; - } - return _Model; +export let _modelForMixin: ModelForMixin; +if (HAS_MODEL_PACKAGE) { + _modelForMixin = require('@ember-data/model/-private')._modelForMixin; } export class DSModelSchemaDefinitionService { @@ -83,13 +80,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 +111,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); - } -} From e7c91f796f207eb86651ab08d14ea05bf6e53ffc Mon Sep 17 00:00:00 2001 From: Chris Thoburn Date: Mon, 25 Nov 2019 22:23:32 -0800 Subject: [PATCH 2/2] ensure modelForMixin is available --- .../model/addon/-private/system/model-for-mixin.ts | 2 +- .../addon/-private/system/schema-definition-service.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/model/addon/-private/system/model-for-mixin.ts b/packages/model/addon/-private/system/model-for-mixin.ts index 3ccd5845bb4..f7555bf0913 100644 --- a/packages/model/addon/-private/system/model-for-mixin.ts +++ b/packages/model/addon/-private/system/model-for-mixin.ts @@ -1,6 +1,6 @@ import Model from '../model'; -import Store from '@ember-data/store'; import { getOwner } from '@ember/application'; +type Store = import('@ember-data/store').default; /* In case someone defined a relationship to a mixin, for example: diff --git a/packages/store/addon/-private/system/schema-definition-service.ts b/packages/store/addon/-private/system/schema-definition-service.ts index d9cc28d087f..1d739299bce 100644 --- a/packages/store/addon/-private/system/schema-definition-service.ts +++ b/packages/store/addon/-private/system/schema-definition-service.ts @@ -10,9 +10,15 @@ import { HAS_MODEL_PACKAGE } from '@ember-data/private-build-infra'; type Model = import('@ember-data/model').default; type ModelForMixin = (store: Store, normalizedModelName: string) => Model | null; -export let _modelForMixin: ModelForMixin; +let _modelForMixin: ModelForMixin; if (HAS_MODEL_PACKAGE) { - _modelForMixin = require('@ember-data/model/-private')._modelForMixin; + let _found; + _modelForMixin = function() { + if (!_found) { + _found = require('@ember-data/model/-private')._modelForMixin; + } + return _found(...arguments); + }; } export class DSModelSchemaDefinitionService {