When LB developer wants to access built-in LB models via app.models, he has to define subclasses in models.json. The current implementation requires that a lot of config options of the base model must be repeated in the subclass definition.
This has several disadvantages:
- It's difficult to add a built-in model to your app, especially if you are new to loopback.
- If we modify the built-in model (e.g. by adding another relation), existing application will break after upgrade.
Below are the use cases I discovered while writing E2E tests for loopback-angular.
datasource
app.model('MyUser', {
options: { base: 'User' },
dataSource: 'db'
});
Result:
assert.js:92
throw new assert.AssertionError({
^
AssertionError: MyUser is referencing a dataSource that does not exist: "undefined"
at modelFromConfig (/Users/bajtos/src/loopback/loopback/node_modules/loopback/lib/application.js:545:3)
at Function.app.model (/Users/bajtos/src/loopback/loopback/node_modules/loopback/lib/application.js:115:38)
[etc.]
Since the new model is a subclass of a built-in model, it should use the same datasource that was configured for the User model.
If the datasource of the base class was not resolved yet, but it has autoAttach property, then the process of attaching the subclass to a datasource should be deferred to loopback.autoAttach.
relations
var user = app.model('user', {
options: {
base: 'User',
},
dataSource: 'db'
});
app.enableAuth();
var credentials = { email: 'foo@foo.com', password: 'password'};
user.create(credentials, function(err) {
if (err) throw err;
user.login(credentials, function(err) {
if (err) throw err;
console.log('login passed');
});
});
Result:
/Users/bajtos/src/loopback/loopback/lib/models/user.js:152
user.accessTokens.create({
^
TypeError: Cannot call method 'create' of undefined
at /Users/bajtos/src/loopback/loopback/lib/models/user.js:152:29
at /Users/bajtos/src/loopback/loopback/lib/models/user.js:202:7
at /Users/bajtos/src/loopback/loopback/node_modules/bcryptjs/bcrypt.min.js:40:101
[etc]
To fix this problem, one has to re-define User relations:
var user = app.model('user', {
options: {
base: 'User',
relations: {
accessTokens: {
model: 'AccessToken',
type: 'hasMany',
foreignKey: 'userId'
}
}
},
dataSource: 'db'
});
When LB developer wants to access built-in LB models via app.models, he has to define subclasses in models.json. The current implementation requires that a lot of config options of the base model must be repeated in the subclass definition.
This has several disadvantages:
Below are the use cases I discovered while writing E2E tests for loopback-angular.
datasource
Result:
Since the new model is a subclass of a built-in model, it should use the same datasource that was configured for the User model.
If the datasource of the base class was not resolved yet, but it has
autoAttachproperty, then the process of attaching the subclass to a datasource should be deferred toloopback.autoAttach.relations
Result:
To fix this problem, one has to re-define User relations: