# Models

# Defining SQL Models

To get started, let’s create a Users model. Models typically live in the app directory.

The easiest way to create a model instance is using the make-sql-model command:

 ts-node maker make-sql-model User

If you would like to generate a database migration when you generate the model, you may use the –migration or –m option:

 ts-node maker make-sql-model User -m

OR

ts-node maker make-sql-model User -migration

# SQL Model Conventions

Now, let’s look at an example User model, which we will use to retrieve and store information from our users database table:

import { Model } from "Elucidate/Database/Model";

class User extends Model {
  // Table name
  static tableName = "users";

  // Model attributes
  id!: number;
  first_name!: string;
  last_name!: string;
  email!: string;
  password!: string;
}

export default User;

# SQL JSON Model Validation

Let's add a validation to our UserModel

import { Model } from "Elucidate/Database/Model";

class User extends Model {
    // Table name
    static tableName = "users";

    // Model attributes
    id!: number;
    first_name!: string;
    last_name!: string;
    email!: string;
    password!: string;

    // Optional JSON schema. This is not the database schema! Nothing is generated
    // based on this. This is only used for validation. Whenever a model instance
    // is created it is checked against this schema. http://json-schema.org/.
    static jsonSchema = {
      type: 'object',
      required: ['name'],

      properties: {
        id: { type: 'integer' },
        first_name: { type: 'string', minLength: 1, maxLength: 255 },
        last_name: { type: 'string', minLength: 1, maxLength: 255 },
        email: { type: 'string', minLength: 1, maxLength: 255 },
        password: { type: 'string', minLength: 1, maxLength: 255 },
      },
    }
}

export default User;

# Relationships

Database tables are often related to one another. For example, a blog post may have many comments or an order could be related to the user who placed it.

  • One To One (BelongsToOneRelation)
  • One To Many (HasManyRelation)
  • Many To Many (ManyToManyRelation)

While relations are usually created between the primary key of one table and a foreign key reference of another table, ExpressWebJs has no such limitations. You can create relationship using any two columns (or any sets of columns). You can even create relation using values nested deep inside json columns.

# One To One (BelongsToOneRelation) Relation

BelongsToOneRelation: Use this relation when the source model has the foreign key

import { Model } from "Elucidate/Database/Model";
import ProfileModel from "App/Model/Profile_model";

class User extends Model {
  static tableName = "users";

  static relationMappings = {
    profile: {
      relation: Model.BelongsToOneRelation,
      modelClass: ProfileModel,
      join: {
        from: "users.id",
        to: "profile.id",
      },
    },
  };
}

export default User;

# One To Many (HasManyRelation) Relation

HasManyRelation: Use this relation when the related model has the foreign key

import { Model } from "Elucidate/Database/Model";
import CarModel from "App/Model/Car_model";

class Person extends Model {
  static tableName = "persons";

  static relationMappings = {
    car: {
      relation: Model.HasManyRelation,
      modelClass: CarModel,
      join: {
        from: "persons.id",
        to: "cars.ownerId",
      },
    },
  };
}

export default Person;

HasOneRelation: Just like HasManyRelation but for one related row

import { Model } from "Elucidate/Database/Model";
import CarModel from "App/Model/Car_model";

class Person extends Model {
  static tableName = "persons";

  static relationMappings = {
    car: {
      relation: Model.HasOneRelation,
      modelClass: CarModel,
      join: {
        from: "persons.id",
        to: "cars.ownerId",
      },
    },
  };
}

export default Person;

# Many To Many (ManyToManyRelation) Relation

ManyToManyRelation: Use this relation when the model is related to a list of other models through a join table

import { Model } from "Elucidate/Database/Model";
import MovieModel from "App/Model/Movie_model";

class Person extends Model {
  static tableName = "persons";

  static relationMappings = {
    movies: {
      relation: Model.ManyToManyRelation,
      modelClass: MovieModel,
      join: {
        from: "persons.id",
        through: {
          // persons_movies is the join table.
          from: "persons_movies.personId",
          to: "persons_movies.movieId",
        },
        to: "movies.id",
      },
    },
  };
}

export default Person;

HasOneThroughRelation: Use this relation when the model is related to a list of other models through a join table

import { Model } from "Elucidate/Database/Model";
import MovieModel from "App/Model/Movie_model";

class Person extends Model {
  static tableName = "persons";

  static relationMappings = {
    movies: {
      relation: Model.HasOneThroughRelation,
      modelClass: MovieModel,
      join: {
        from: "persons.id",
        through: {
          // persons_movies is the join table.
          from: "persons_movies.personId",
          to: "persons_movies.movieId",
        },
        to: "movies.id",
      },
    },
  };
}

export default Person;

# Defining NoSQL Models

To get started, let’s create a Users model. Models typically live in the app directory.

The easiest way to create a nosql model instance is using the make-nosql-model command:

 ts-node maker make-nosql-model User

# NOSQL Model Conventions

Now, let’s look at an example User model, which we will use to retrieve and store information from our users database table:

"use strict";
import { mongoose, Schema, Document } from "Elucidate/Database/NoSQLModel";
import uniqueValidator from "mongoose-unique-validator";

export interface UserInterface extends Document {
  first_name: string;
  last_name: string;
  email: string;
  password: string;
}

const UserSchema: Schema = new Schema({
  first_name: { type: String, required: true },
  first_name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

UserSchema.set("timestamps", true);
UserSchema.plugin(uniqueValidator);

const User = mongoose.model<UserInterface>("User", UserSchema);

export default User;