executor: Split model boot into two phases
In the first phase, all models are defined. In the second phase, models are configured, attached to data-sources and exposed on the app object. This way when the `attached` Model event is emitted, all models are already defined and thus a listener can get reference of any other model used in the app.
This commit is contained in:
parent
b887b33b57
commit
ef72efa70b
|
@ -95,6 +95,17 @@ function setupDataSources(app, instructions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupModels(app, instructions) {
|
function setupModels(app, instructions) {
|
||||||
|
defineModels(instructions);
|
||||||
|
|
||||||
|
instructions.models.forEach(function(data) {
|
||||||
|
// Skip base models that are not exported to the app
|
||||||
|
if (!data.config) return;
|
||||||
|
|
||||||
|
app.model(data._model, data.config);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function defineModels(instructions) {
|
||||||
instructions.models.forEach(function(data) {
|
instructions.models.forEach(function(data) {
|
||||||
var name = data.name;
|
var name = data.name;
|
||||||
var model;
|
var model;
|
||||||
|
@ -122,10 +133,7 @@ function setupModels(app, instructions) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip base models that are not exported to the app
|
data._model = model;
|
||||||
if (!data.config) return;
|
|
||||||
|
|
||||||
app.model(model, data.config);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,6 @@ describe('executor', function() {
|
||||||
}.toString());
|
}.toString());
|
||||||
|
|
||||||
boot.execute(app, someInstructions({
|
boot.execute(app, someInstructions({
|
||||||
dataSources: { db: { connector: 'memory' } },
|
|
||||||
models: [
|
models: [
|
||||||
{
|
{
|
||||||
name: 'Customer',
|
name: 'Customer',
|
||||||
|
@ -83,7 +82,6 @@ describe('executor', function() {
|
||||||
|
|
||||||
it('defines model without attaching it', function() {
|
it('defines model without attaching it', function() {
|
||||||
boot.execute(app, someInstructions({
|
boot.execute(app, someInstructions({
|
||||||
dataSources: { db: { connector: 'memory' } },
|
|
||||||
models: [
|
models: [
|
||||||
{
|
{
|
||||||
name: 'Vehicle',
|
name: 'Vehicle',
|
||||||
|
@ -113,6 +111,35 @@ describe('executor', function() {
|
||||||
assert.equal(app.models.User.dataSource, app.dataSources.theDb);
|
assert.equal(app.models.User.dataSource, app.dataSources.theDb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('defines all models first before running the config phase', function() {
|
||||||
|
appdir.writeFileSync('models/Customer.js', 'module.exports = ' +
|
||||||
|
function(Customer/*, Base*/) {
|
||||||
|
Customer.on('attached', function() {
|
||||||
|
Customer._modelsWhenAttached =
|
||||||
|
Object.keys(Customer.modelBuilder.models);
|
||||||
|
});
|
||||||
|
}.toString());
|
||||||
|
|
||||||
|
boot.execute(app, someInstructions({
|
||||||
|
models: [
|
||||||
|
{
|
||||||
|
name: 'Customer',
|
||||||
|
config: { dataSource: 'db' },
|
||||||
|
definition: { name: 'Customer' },
|
||||||
|
sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'UniqueName',
|
||||||
|
config: { dataSource: 'db' },
|
||||||
|
definition: { name: 'UniqueName' },
|
||||||
|
sourceFile: undefined
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(app.models.Customer._modelsWhenAttached).to.include('UniqueName');
|
||||||
|
});
|
||||||
|
|
||||||
it('instantiates data sources', function() {
|
it('instantiates data sources', function() {
|
||||||
boot.execute(app, dummyInstructions);
|
boot.execute(app, dummyInstructions);
|
||||||
assert(app.dataSources);
|
assert(app.dataSources);
|
||||||
|
@ -257,7 +284,7 @@ function someInstructions(values) {
|
||||||
var result = {
|
var result = {
|
||||||
app: values.app || {},
|
app: values.app || {},
|
||||||
models: values.models || [],
|
models: values.models || [],
|
||||||
dataSources: values.dataSources || {},
|
dataSources: values.dataSources || { db: { connector: 'memory' } },
|
||||||
files: {
|
files: {
|
||||||
boot: []
|
boot: []
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue