From 2b2829fbca3d1cfc5290fb14848de6e7e4ed0961 Mon Sep 17 00:00:00 2001 From: Zachary Golba Date: Sun, 14 Aug 2016 16:11:41 -0400 Subject: [PATCH] fix: model-less controllers prevent applications from starting (#315) --- src/packages/application/initialize.js | 4 +- src/packages/controller/index.js | 48 ++++++++++++++++--- src/packages/route/action/index.js | 20 ++++---- src/packages/route/params/index.js | 24 ++++++---- .../route/params/utils/get-data-params.js | 18 ++++--- .../route/params/utils/get-query-params.js | 34 ++++++++----- 6 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/packages/application/initialize.js b/src/packages/application/initialize.js index ce892a46..3c580530 100644 --- a/src/packages/application/initialize.js +++ b/src/packages/application/initialize.js @@ -11,6 +11,8 @@ import loader from '../loader'; import { ControllerMissingError, SerializerMissingError } from './errors'; +import { tryCatchSync } from '../../utils/try-catch'; + import type Application, { Application$opts } from './index'; // eslint-disable-line no-unused-vars, max-len /** @@ -83,7 +85,7 @@ export default async function initialize(app: T, { controllers.forEach((controller, key) => { if (key !== 'application') { - const model = store.modelFor(singularize(key)); + const model = tryCatchSync(() => store.modelFor(singularize(key))); controller = new controller({ store, diff --git a/src/packages/controller/index.js b/src/packages/controller/index.js index 55188734..c3b669f4 100644 --- a/src/packages/controller/index.js +++ b/src/packages/controller/index.js @@ -22,6 +22,26 @@ import type { Controller$opts } from './interfaces'; * and returns data relative to what the client has request. */ class Controller { + /** + * A boolean value representing whether or not a `Controller` has a backing + * `Model`. + * + * @property hasModel + * @memberof Controller + * @instance + */ + hasModel: boolean; + + /** + * A boolean value representing whether or not a `Controller` has a backing + * `Serializer`. + * + * @property hasSerializer + * @memberof Controller + * @instance + */ + hasSerializer: boolean; + /** * The number of records to return for the #index action when a `?limit` * parameter is not specified. @@ -111,10 +131,12 @@ class Controller { controllers, parentController }: Controller$opts) { + const hasModel = Boolean(model); + const hasSerializer = Boolean(serializer); let attributes = []; let relationships = []; - if (model && serializer) { + if (hasModel && hasSerializer) { const { primaryKey, attributeNames, relationshipNames } = model; const { attributes: serializedAttributes } = serializer; @@ -143,6 +165,20 @@ class Controller { configurable: false }, + hasModel: { + value: hasModel, + writable: false, + enumerable: true, + configurable: false + }, + + modelName: { + value: hasModel ? model.modelName : '', + writable: false, + enumerable: false, + configurable: false + }, + serializer: { value: serializer, writable: false, @@ -150,15 +186,15 @@ class Controller { configurable: false }, - store: { - value: store, + hasSerializer: { + value: hasSerializer, writable: false, - enumerable: false, + enumerable: true, configurable: false }, - modelName: { - value: model ? model.modelName : '', + store: { + value: store, writable: false, enumerable: false, configurable: false diff --git a/src/packages/route/action/index.js b/src/packages/route/action/index.js index 3b6feea3..8dc2ddc7 100644 --- a/src/packages/route/action/index.js +++ b/src/packages/route/action/index.js @@ -14,16 +14,18 @@ export function createAction( controller: Controller, action: Action ): Array> { - switch (name) { - case 'index': - action = collection(action); - break; + if (controller.hasModel && controller.hasSerializer) { + switch (name) { + case 'index': + action = collection(action); + break; - case 'create': - case 'update': - case 'show': - action = member(action); - break; + case 'create': + case 'update': + case 'show': + action = member(action); + break; + } } function __FINAL__HANDLER__(req, res) { diff --git a/src/packages/route/params/index.js b/src/packages/route/params/index.js index 9581b108..1a5b3dcc 100644 --- a/src/packages/route/params/index.js +++ b/src/packages/route/params/index.js @@ -73,18 +73,22 @@ export function defaultParamsFor({ action: string; controller: Controller }): Object { - switch (action) { - case 'index': - return getDefaultCollectionParams(controller); + if (controller.hasModel) { + switch (action) { + case 'index': + return getDefaultCollectionParams(controller); - case 'show': - case 'create': - case 'update': - case 'destroy': - return getDefaultMemberParams(controller); + case 'show': + case 'create': + case 'update': + case 'destroy': + return getDefaultMemberParams(controller); - default: - return {}; + default: + return {}; + } + } else { + return {}; } } diff --git a/src/packages/route/params/utils/get-data-params.js b/src/packages/route/params/utils/get-data-params.js index c6eaea51..0a856297 100644 --- a/src/packages/route/params/utils/get-data-params.js +++ b/src/packages/route/params/utils/get-data-params.js @@ -144,17 +144,21 @@ export default function getDataParams( controller: Controller, includeID: boolean ): [string, ParameterLike] { - let params = [ - getTypeParam(controller), - getAttributesParam(controller), - getRelationshipsParam(controller) - ]; + let params = [getTypeParam(controller)]; - if (includeID) { + if (controller.hasModel) { params = [ - getIDParam(controller), + getAttributesParam(controller), + getRelationshipsParam(controller), ...params ]; + + if (includeID) { + params = [ + getIDParam(controller), + ...params + ]; + } } return ['data', new ParameterGroup(params, { diff --git a/src/packages/route/params/utils/get-query-params.js b/src/packages/route/params/utils/get-query-params.js index 22bfbf5d..773931c1 100644 --- a/src/packages/route/params/utils/get-query-params.js +++ b/src/packages/route/params/utils/get-query-params.js @@ -124,11 +124,15 @@ function getCustomParams({ export function getMemberQueryParams( controller: Controller ): Array<[string, ParameterLike]> { - return [ - getFieldsParam(controller), - getIncludeParam(controller), - ...getCustomParams(controller) - ]; + if (controller.hasModel) { + return [ + getFieldsParam(controller), + getIncludeParam(controller), + ...getCustomParams(controller) + ]; + } else { + return getCustomParams(controller); + } } /** @@ -137,12 +141,16 @@ export function getMemberQueryParams( export function getCollectionQueryParams( controller: Controller ): Array<[string, ParameterLike]> { - return [ - getPageParam(), - getSortParam(controller), - getFilterParam(controller), - getFieldsParam(controller), - getIncludeParam(controller), - ...getCustomParams(controller) - ]; + if (controller.hasModel) { + return [ + getPageParam(), + getSortParam(controller), + getFilterParam(controller), + getFieldsParam(controller), + getIncludeParam(controller), + ...getCustomParams(controller) + ]; + } else { + return getCustomParams(controller); + } }