Skip to main content

Models

Framework based on mongoose library and provide direct access to mongoose.

It uses ES6 class variant of mongoose to init. Also you can access framework

Model take care about database connection

note

Models files part of framework inheritance process .

Access mongoose instance

Inside the class mongoose avaialable as

this.mongooseModel

Basic model

const AbstractModel = require('@adaptivestone/framework/modules/AbstractModel');

class SomeModel extends AbstractModel {
constructor(app) {
super(app);
// you can put some init stuff
}


initHooks() {
super.initHooks();
// place to init plugins, indexes, etc.
// As it happens after loaded class into mongoos, but before mongoose inited class
// this.mongooseSchema.plugin(PLUGIN_NAME);
}

// here mongoose scheme go
// this is a fullu mongoose scheme
// Please reffer to mongoose documentation https://mongoosejs.com/docs/guide.html
get modelSchema() {
return {
someString: { type: String, required: true },
firstName: String,
lastName: String,
email: String
};
}

// Static method will be part on monngose class
// this.app.getModel('SomeModel').someStaticMethod()
// TODO access to APP instance from static methods
static async someStaticMethod() {
const somedata = await this.findByIdAndUpdate(
//.....
);
return somedata;
}

// any methods will be part on instance method
// await this.app.getModel('SomeModel').findById(124).someInstanceMethod()
async someInstanceMethod(){
// you can access app into the instance method
const { app } = this.constructor.getSuper();

// inside of instance method you can access model data
this.someString;

}

// any getters will became a mongoose virtual
// const SomeModels = this.app.getModel("SomeModel").
// const someModelInstance = await SomeModel().create({ email: 'test@gmail.com' });;
// `domain` is now a property on SomeModels documents.
// someModelInstance.domain; // 'gmail.com'
get domain() {
return this.email.slice(this.email.indexOf('@') + 1);

}

// setters also be an virtual
// const SomeModels = this.app.getModel("SomeModel").
// const someModelInstance = new SomeModel();
// Vanilla JavaScript assignment triggers the setter
// someModelInstance.fullName = 'Jean-Luc Picard';
set fullName(v) {
// `v` is the value being set, so use the value to set
// `firstName` and `lastName`.
const firstName = v.substring(0, v.indexOf(' '));
const lastName = v.substring(v.indexOf(' ') + 1);
this.set({ firstName, lastName });
}


}

module.exports = SomeModel;

tip

If you have some relations ("ref") on a mongoose model that you should care to load schema. As mongoose can only build relationships with schemas in memory. Google place to do that - inside constructor. Be aware on loop linking models

constructoror(app){
super(app);
this.app.getModel(“ReferenceModelName”);
}
danger

Models united onse per process and then united instances cached. Do NOT expect constructor or init hook calls on every model loading

tip

Please do not name the model in plural form.

Bad - Coins

Good - Coin

API

getModel(modelName: string): MongooseModel<any>;

Example:

const UserModel = this.app.getModel("User");
const userInstace = await UserModel.findOne({email:"user@email.com"})

Configuration

Main configuration variable "MONGO_DSN" environment variable. Based on it model will made connection to the database

Built-in models

Framework came with few built-in models.

User

It's a part of the authorization system. It takes care of storing users, hash passwords and provides some basic functions for token generation and getting users.

If you want to have your own user implementation you should overwrite it or disable.

Auth controller depends on this model

API

const UserModel = this.app.getModel("User");
const user = await UserModel.getUserByEmailAndPassword("email","password"):
const userToken = await user.generateToken(); // generate and store token on databse
const userPublic = await user.getPublic();
const hashedPassword = await UserModel.hashPassword("password");
const sameUser = await UserModel.getUserByToken(userToken);
const sameUserAgain = await UserModel.getUserByEmail(user.email);
const recoveryToken = await UserModel.generateUserPasswordRecoveryToken(user);
const sameUSerAgain2 = await UserModel.getUserByPasswordRecoveryToken(recoveryToken);
const isSuccess = await user.sendPasswordRecoveryEmail(i18n);
const verificationToken = await UserModel.generateUserVerificationToken(user);
const sameUSerAgain3 = awaitUserModel.getUserByVerificationToken(verificationToken);
await UserModel.removeVerificationToken(verificationToken);
const isSuccess2 = await user.sendVerificationEmail(i18n);

Migration

Migration model it's helper for migration subsystems. It stores migrated files to make sure that migrated executed once

Please refer to CLI/migrations for more details

You probably should not use this model directly

Sequence

Sequence allows you to generate sequences by name. This is cross server safe method to generate sequences in distributed environment

const SequenceModel = this.app.getModel('Sequence');
// will be 1
const someTypeSequence = await SequenceModel.getSequence('someType');
// will be 2
const someTypeSequence2 = await SequenceModel.getSequence('someType');
// will be 1 as type is another
const someAnotherTypeSequence = await SequenceModel.getSequence(
'someAnotherType',
);