Loopback: Created a custom model extending the base model, the data is inserted into the base model, not to the custom model.

Created on 24 Mar 2017  ·  7Comments  ·  Source: strongloop/loopback

How to create a 3rd party login that insert data to custom model which inherit loopback base models, using loopback-component-passport?

When created a custom model extending the base model, the data is inserted into the base model, not to the custom model.

model-config.json

{
  "_meta": {
    "sources": [
      "../common/models",
      "./models",
      "./node_modules/loopback-component-passport/lib/models"
    ]
  },
  "User": {
    "dataSource": "mongoDb",
    "public": false
  },
  "AccessToken": {
    "dataSource": "mongoDb",
    "public": false
  },
  "customer": {
    "dataSource": "mongoDb",
    "public": true
  },
  "accessToken": {
    "dataSource": "mongoDb",
    "public": false
  },
  "customerCredential": {
    "dataSource": "mongoDb",
    "public": false
  },
  "customerIdentity": {
    "dataSource": "mongoDb",
    "public": false
  },
  "ACL": {
    "dataSource": "mongoDb",
    "public": false
  },
  "RoleMapping": {
    "dataSource": "mongoDb",
    "public": false
  },
  "Role": {
    "dataSource": "mongoDb",
    "public": false
  }
}

The passport configurator
server.js

passportConfigurator.init();

passportConfigurator.setupModels({
  userModel: app.models.customer,
  userIdentityModel: app.models.customerIdentity,
  userCredentialModel: app.models.customerCredential,
});

Models

customer.json
{
  "name": "customer",
  "plural": "customers",
  "base": "User",
  "relations": {
    "accessTokens": {
      "type": "hasMany",
      "model": "accessToken",
      "foreignKey": "customerId"
    },
    "customeridentities": {
      "type": "hasMany",
      "model": "customerIdentity",
      "foreignKey": "customerId"
    },
    "customercredentials": {
      "type": "hasMany",
      "model": "customerCredential",
      "foreignKey": "customerId"
    }
  },
  "validations": [],
  "acls": [],
  "methods": []
}

customer-credential.json

{
  "name": "customerCredential",
  "plural": "customerCredentials",
  "base": "UserCredential",
  "properties": {},
  "validations": [],
  "relations": {
    "customer": {
      "type": "belongsTo",
      "model": "customer",
      "foreignKey": "customerId"
    }
  },
  "acls": [],
  "methods": []
}

accessToken.json

{
  "name": "accessToken",
  "plural": "accessTokens",
  "base": "AccessToken",
  "properties": {},
  "validations": [],
  "relations": {
    "customer": {
      "type": "belongsTo",
      "model": "customer",
      "foreignKey": "customerId"
    }
  },
  "acls": [],
  "methods": []
}

customerIdentity.json

{
  "name": "customerIdentity",
  "plural": "customerIdentities",
  "base": "UserIdentity",
  "properties": {},
  "validations": [],
  "relations": {
    "customer": {
      "type": "belongsTo",
      "model": "customer",
      "foreignKey": "customerId"
    }
  },
  "acls": [],
  "methods": []
}

This above is the configuration in code.

But in the database the table created were User and AccessToken not customer and accessToken.

When I remove the user and access token from the model-config.json.

  "User": {
    "dataSource": "mongoDb",
    "public": false
  },
  "AccessToken": {
    "dataSource": "mongoDb",
    "public": false
  }

The customer table and accessToken table (custom tables) were created in the mongo database. But I get the following error message in console.

Error Message

The model "accessToken" configures "belongsTo User-like models" relation with target model "User". However, the model "User" is not attached to the application and therefore cannot be used by this relation. This typically happens when the application has a custom custom User subclass, but does not fix AccessToken relations to use this new model.
But when the User and AccessToken are added to the model-config the table created in the db is not the custom dbs customer and accessToken. Its the base data models User and AccessToken.

The link to the sandbox is given below.
https://github.com/samithks/loopback-sandbox

stale

Most helpful comment

Worth mentioning that the docs here provide what's needed.

I would add that if you are updating from loopback 3.6 or older, you have to add two VARCHAR columns to your custom access token table in your db as per https://github.com/strongloop/loopback/issues/3422

And every model that extends the built-in User model should have this in its relations:

      "accessTokens": {
        "type": "hasMany",
        "model": "YourCustomAccessToken",
        "polymorphic": {
          "foreignKey": "userId",
          "discriminator": "principalType"
        },
        "options": {
          "disableInclude": true
        }
      }

All 7 comments

Did you try to remove user and access token from the model-config.json and just use customAccessToken & customUser but you should

add this to your customUser (in your case customer)

"accessTokens": { //dont change this name
      "type": "hasMany",
      "model": "customAccessToken",
      "foreignKey": "userId",
      "options": {
        "disableInclude": true
      }
    }

and also add this to your customAccessToken (in your case accessToken)

"user": { //dont change this name
      "type": "belongsTo",
      "model": "customUser",
      "foreignKey": "userId"
   }

this worked for me

@samithks
just ignore the warning message and remove base User and AccessToken in your model-config.json at the moment. A fix is being worked out for the warning message. Please confirm whether it's working then.

@ebarault
Thanks.

I removed the User and AccessToken the model-config.json.

Now the model-config is like the below one

  "accessToken": {
  "dataSource": "mongo-db",
  "public": false
  },
  "CustomerCredential": {
  "dataSource": "mongo-db",
  "public": false
  },
  "CustomerIdentity": {
  "dataSource": "mongo-db",
  "public": false
  },
  "Customer": {
  "dataSource": "mongo-db",
  "public": true
  }

customer.json

  "relations": {
    "accessTokens": {
      "type": "hasMany",
      "model": "accessToken",
      "foreignKey": "userId"
    },
    "credentials": {
      "type": "hasMany",
      "model": "CustomerCredential",
      "foreignKey": "userId"
    },
    "identities": {
      "type": "hasMany",
      "model": "CustomerIdentity",
      "foreignKey": "userId"
    }
  }

access-token.json

  "relations": {
    "user": {
      "type": "belongsTo",
      "model": "Customer",
      "foreignKey": "userId"
    }
  },

Now the warning message is not showing and as far working properly.

@b3rew
Hi,
Thanks for your reply.
Ya, I tried that already and working.
I need to use relation name as user in access-token and accessTokens in customer.json.
Not able to change that relation names and not able to include User and AccessToken in model-config.json.

Worth mentioning that the docs here provide what's needed.

I would add that if you are updating from loopback 3.6 or older, you have to add two VARCHAR columns to your custom access token table in your db as per https://github.com/strongloop/loopback/issues/3422

And every model that extends the built-in User model should have this in its relations:

      "accessTokens": {
        "type": "hasMany",
        "model": "YourCustomAccessToken",
        "polymorphic": {
          "foreignKey": "userId",
          "discriminator": "principalType"
        },
        "options": {
          "disableInclude": true
        }
      }

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository.

Was this page helpful?
0 / 5 - 0 ratings