Skip to content

LoopBack models should inherit config.options from the parent #157

Description

@bajtos

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:

  1. It's difficult to add a built-in model to your app, especially if you are new to loopback.
  2. 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'
});

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions