# 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;