最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - StrongLoop : How to define models in models directory at loopback.boot() time? - Stack Overflow

programmeradmin1浏览0评论

In the Loopback documentation Initializing the application, it is said two things :

First :

Loopback.boot() loads data sources and models based on json definition files, or given options, then, loads all js files from models/ and boot/ directories

Then :

"Don't bine using app.boot() and app.model(name, config) in multiple files because it may result in models being undefined due to race conditions. To avoid this when using app.boot() make sure all models are passed as part of the models definition."

Doesn't the two seem a contradiction ?

I have many models to define, that I don't want to define in a single enormous json file, and hence want to place one js file per model in the said models/ directory to be loaded at boot time.

What I did, for the moment, is define a model in models/ExampleModel.js like so :

    var properties = {
        fieldOne: { type: String, required: true },
        otherField: { type: Number }
    };

    var options = {
        relations: {
            collections: {
                type: "belongsTo",
                model: "user"
            }
        }
    };

    var Model = require('loopback').Model;
    module.exports = Model.extend('ExampleModel', properties, options);

The thing is : during boot(), the model is loaded, but not attached to the app or any datasource. It is not exposed to REST API.

I tried a small addition to models.json to enable the model in the app :

"examplemodel": {
    "options": {
        "base": "ExampleModel"
    },
    "dataSource": "db",
    "public": true
}

It does not work, Loopback throw a Class not found exception.

I also thought about using app.model() instead of Model.extend(), but I don't know how to access app in the required model js files.

Question: how to define models in models/ directory and still attach them to app, datasource and REST API, while still relying on all boot() mechanism ?

In the Loopback documentation Initializing the application, it is said two things :

First :

Loopback.boot() loads data sources and models based on json definition files, or given options, then, loads all js files from models/ and boot/ directories

Then :

"Don't bine using app.boot() and app.model(name, config) in multiple files because it may result in models being undefined due to race conditions. To avoid this when using app.boot() make sure all models are passed as part of the models definition."

Doesn't the two seem a contradiction ?

I have many models to define, that I don't want to define in a single enormous json file, and hence want to place one js file per model in the said models/ directory to be loaded at boot time.

What I did, for the moment, is define a model in models/ExampleModel.js like so :

    var properties = {
        fieldOne: { type: String, required: true },
        otherField: { type: Number }
    };

    var options = {
        relations: {
            collections: {
                type: "belongsTo",
                model: "user"
            }
        }
    };

    var Model = require('loopback').Model;
    module.exports = Model.extend('ExampleModel', properties, options);

The thing is : during boot(), the model is loaded, but not attached to the app or any datasource. It is not exposed to REST API.

I tried a small addition to models.json to enable the model in the app :

"examplemodel": {
    "options": {
        "base": "ExampleModel"
    },
    "dataSource": "db",
    "public": true
}

It does not work, Loopback throw a Class not found exception.

I also thought about using app.model() instead of Model.extend(), but I don't know how to access app in the required model js files.

Question: how to define models in models/ directory and still attach them to app, datasource and REST API, while still relying on all boot() mechanism ?

Share Improve this question edited Sep 30, 2014 at 13:40 Craig Ringer 325k79 gold badges732 silver badges812 bronze badges asked Feb 11, 2014 at 16:23 PandaioloPandaiolo 11.6k5 gold badges41 silver badges72 bronze badges 2
  • I could also set a grunt task to bine different files in another directory than models/, to build models.json, but if loopback scans that directory, I suppose it can be used, and I'd be glad to know what's the best practice about it. – Pandaiolo Commented Feb 11, 2014 at 16:31
  • 1 I have filled a GitHub issue for app.boot() to support multiple json files - github./strongloop/loopback/issues/177 – Miroslav Bajtoš Commented Feb 11, 2014 at 19:20
Add a ment  | 

2 Answers 2

Reset to default 9

I also thought about using app.model() instead of Model.extend(), but I don't know how to access app in the required model js files.

If you scaffolded your project using slc lb project, the app object should be exported by the main app.js file.

So you can get the app object this way:

// in models/example-model.js
var app = require('../app.js')

Once you have the app object, you can call app.model as you correctly pointed out.

var properties = {
  fieldOne: { type: String, required: true },
  otherField: { type: Number }
};

var options = {
    relations: {
        collections: {
            type: "belongsTo",
            model: "user"
        }
    }
};

app.model('ExampleModel', {
  properties: properties, 
  options: options,
  dataSource: 'db' // replace with the correct name
);

// you can access the model now via
//   app.models.ExampleModel

I gave it a try, by realizing that required models (from models/ directory) are not stored anywhere, so I modified this, in the node_modules/loopback/lib/application.js :

498 - var requiredModels = requireDir(path.join(appRootDir, 'models'));
498 + app.requiredModels = requireDir(path.join(appRootDir, 'models'));

That way, I can access the required models after the app.boot() call in app.js :

app.boot(__dirname);
Object.keys(app.requiredModels).map(function(modelName) {
    app.model(modelName, {dataSource: 'db'});
});

It kinda works : model is exposed to the REST API, but not its relations, any ideas why ?

Also, I modified a core file from loopback distribution, so it will break at the next update...

发布评论

评论列表(0)

  1. 暂无评论