diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index 277ff633b40..8a57b772ca3 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -25,7 +25,6 @@ import Controller from '@ember/controller'; import { assert, info, isTesting } from '@ember/debug'; import { dependentKeyCompat } from '@ember/object/compat'; import { once } from '@ember/runloop'; -import { classify } from '@ember/string'; import { DEBUG } from '@glimmer/env'; import { Template, TemplateFactory } from '@glimmer/interfaces'; import { @@ -1736,16 +1735,18 @@ class Route extends EmberObject.extend(ActionHandler, Evented) implements IRoute protected get store() { let owner = getOwner(this); let routeName = this.routeName; - let namespace = get(this, '_router.namespace'); return { find(name: string, value: unknown) { let modelClass: any = owner.factoryFor(`model:${name}`); assert( - `You used the dynamic segment ${name}_id in your route ${routeName}, but ${namespace}.${classify( - name - )} did not exist and you did not override your route's \`model\` hook.`, + `You used the dynamic segment \`${name}_id\` in your route ` + + `\`${routeName}\` for which Ember requires you provide a ` + + `data-loading implementation. Commonly, that is done by ` + + `adding a model hook implementation on the route ` + + `(\`model({${name}_id}) {\`) or by injecting an implemention of ` + + `a data store: \`@service store;\`.`, Boolean(modelClass) ); @@ -1755,7 +1756,22 @@ class Route extends EmberObject.extend(ActionHandler, Evented) implements IRoute modelClass = modelClass.class; - assert(`${classify(name)} has no method \`find\`.`, typeof modelClass.find === 'function'); + assert( + `You used the dynamic segment \`${name}_id\` in your route ` + + `\`${routeName}\` for which Ember requires you provide a ` + + `data-loading implementation. Commonly, that is done by ` + + `adding a model hook implementation on the route ` + + `(\`model({${name}_id}) {\`) or by injecting an implemention of ` + + `a data store: \`@service store;\`.\n\n` + + `Rarely, applications may attempt to use a legacy behavior where ` + + `the model class (in this case \`${name}\`) is resolved and the ` + + `\`find\` method on that class is invoked to load data. In this ` + + `application, a model of \`${name}\` was found but it did not ` + + `provide a \`find\` method. You should not add a \`find\` ` + + `method to your model. Instead, please implement an appropriate ` + + `\`model\` hook on the \`${routeName}\` route.`, + typeof modelClass.find === 'function' + ); return modelClass.find(value); }, @@ -2456,3 +2472,4 @@ Route.reopen({ }); export default Route; +export default Route; diff --git a/packages/@ember/-internals/routing/tests/system/route_test.js b/packages/@ember/-internals/routing/tests/system/route_test.js index fbc5de2c80d..2b6fd159f29 100644 --- a/packages/@ember/-internals/routing/tests/system/route_test.js +++ b/packages/@ember/-internals/routing/tests/system/route_test.js @@ -70,14 +70,31 @@ moduleFor( let owner = buildOwner(); let Post = EmberObject.extend(); - owner.register('route:index', EmberRoute); + owner.register( + 'route:index', + EmberRoute.extend({ + routeName: 'index', + }) + ); owner.register('model:post', Post); route = owner.lookup('route:index'); expectAssertion(function () { route.findModel('post', 1); - }, 'Post has no method `find`.'); + }, `You used the dynamic segment \`post_id\` in your route ` + + `\`index\` for which Ember requires you provide a ` + + `data-loading implementation. Commonly, that is done by ` + + `adding a model hook implementation on the route ` + + `(\`model({post_id}) {\`) or by injecting an implemention of ` + + `a data store: \`@service store;\`.\n\n` + + `Rarely, applications may attempt to use a legacy behavior where ` + + `the model class (in this case \`post\`) is resolved and the ` + + `\`find\` method on that class is invoked to load data. In this ` + + `application, a model of \`post\` was found but it did not ` + + `provide a \`find\` method. You should not add a \`find\` ` + + `method to your model. Instead, please implement an appropriate ` + + `\`model\` hook on the \`index\` route.`); runDestroy(owner); } @@ -86,13 +103,23 @@ moduleFor( runDestroy(route); let owner = buildOwner(); - owner.register('route:index', EmberRoute); + owner.register( + 'route:index', + EmberRoute.extend({ + routeName: 'index', + }) + ); route = owner.lookup('route:index'); expectAssertion(function () { route.model({ post_id: 1 }); - }, /You used the dynamic segment post_id in your route undefined, but <.*:ember\d+>.Post did not exist and you did not override your route's `model` hook./); + }, `You used the dynamic segment \`post_id\` in your route ` + + `\`index\` for which Ember requires you provide a ` + + `data-loading implementation. Commonly, that is done by ` + + `adding a model hook implementation on the route ` + + `(\`model({post_id}) {\`) or by injecting an implemention of ` + + `a data store: \`@service store;\`.`); runDestroy(owner); }