0
votes

Individual models can be fetched with store.findRecord(modelTypeName, id);; how can I get a list of all the possible modelTypeNames available in my app?

I'm specifically trying to do this from within an app initializer.

I'm using ember-cli version 1.13.8 with Ember 2.1.0

Edit: This question is somewhat of a duplicate, but it's not clear in what context he's working. It seems like introspection should be easier to achieve without hacks in an (instance) initializer where you're supposed to access to the app (instance) than in the general case, so hopefully this question can accumulate some useful answers specific to that context.

1

1 Answers

1
votes

tl;dr:

From within your code (eg. an instance intializer):

import ModuleRegistry from 'ember-resolver/utils/module-registry';
    ...
var modelRegexp = /^[a-zA-Z0-9-_]+\/models\/(.*)$/;
var modelNames = new ModuleRegistry()
  .moduleNames()
  .filter((name) => modelRegexp.test(name))
  .map((name) => modelRegexp.exec(name)[1]);

If you need a hacky one-liner from the debugging console on a running app:

YourAppName.__container__
  .lookup('container-debug-adapter:main')
  .catalogEntriesByType('model')
  .filter((name) => YourAppName.__container__.lookupFactory('model:' + name));

Or, get only the models already loaded with:

Object.keys(YourAppName.__container__.factoryCache).filter((i) => i.startsWith('model:'))

Longer answer:

These approaches are kind of complicated, assume you aren't using pods or anything else non-standard, and rely on undocumented internal APIs. They're also specific to ember-resolver (the ES6-module-based lookup system used in ember-cli and Ember App Kit). So not ideal.

It should actually be as simple as:

var debugAdapter = appInstance.lookup('container-debug-adapter:main');
var modelNames = debugAdapter.catalogEntriesByType('model');

Unfortunately the ContainerDebugAdapter class included with ember-resolver is buggy, so it will return a bunch of extra items.

Hopefully this will be fixed soon (I've filed bug report), but until then, the code above should serve.

Interestingly, this string-based matching is basically what the ContainerDebugAdapter does (incorrectly) internally. The ContainerDebugAdapter that ships with Ember does the same sort of thing to look up objects in the app-wide namespaces (Ember.Namespace.NAMESPACES).

I realize that Ember (and ember-cli especially) is very name-convention-driven, but this regex matching feels a little crazy. It seems to me that, ideally, we'd instead be importing the DS.Model class and just getting it's subclasses. Unfortunately it seems that isn't (easily) possible: as far as I can tell, an Ember class stores a reference to it's superclass(es), but not to it's subclasses.