Skip to main content

๐Ÿ“€ Models

If you're familiar with object-oriented, this is nothing more or less than a system of linking to the database in the form of objects.

Otherwise, imagine you can create a user, an animal or something else that we will call object and save it into the database. In classic SQL system you have to send hard requests to insert, select, update, delete, etc in your database. Here we have Models, an easy way to manipulate data from database, thank's to objects saved in your variables.

Let's create a User object in ./sources/modules/<module_name>/models/ with username, email and created_at as fields (dont forget to replace <module_name> by your module's name).

class User extends AModel
{
static table = 'users';
static fields = {
username: 'string',
email: 'string',
created_at: 'datetime'
};
}

We have to asign a database to our User Models, we can do it thank's to use method and we must do it inside init.js. At the same time, we are going to initialise the table in the database using the init method.

const { clappybot } = require("clappybot")
const { User } = require("./models/User")

async function init_module(connection)
{
// Define the database to be used by your model
User.use(clappybot.database);

// Initialise the table (this sould be in your init.js)
User.init()
}

module.exports = {
init_module
}

๐Ÿ†• Create new Modelโ€‹

By convention, you should create your models in the models folder of the module : ./sources/modules/<module_name>/models/ (dont forget to replace <module_name> by your module's name). Like this :

const { AModel } = require("clappybot");

class User extends AModel
{
static table = 'users';
static fields = {
username: 'string',
email: 'string',
created_at: 'datetime'
};
}

module.exports = {
User
}

At first, import the abstract class ' AModels ' which our model will inherit

const { AModel } = require(clappybot);

Create your model as follows (replace <ModelName> by the name of your model):

class <ModelName> extends AModel

Set a table name (replace <table_name> with the name you want for your table):

static table = '<table_name>';

Define fields (you will see below the possible kinds of fields):

static fields = {
example: "text"
}

Dont forget to export your Model so you can import it inside other files (replace <ModelName> by the name of your model):

module.exports = {
<ModelName>
}

๐Ÿ“ Fieldsโ€‹

โŽฏ โ„น๏ธ Field type โ†’ SQL Type

integer โ†’ INT DEFAULT 0 a classic number (INT32), that can be a negative.

size โ†’ UNSIGNED INT โš ๏ธ only supported by mariadb/mysql, it's a number (INT32) but that can't be negative.

bigint โ†’ UNSIGNED BIGINT โš ๏ธ only supported by mariadb/mysql, it's a very big int (INT64) and that can't be negative.

datetime โ†’ DATETIME DEFAULT CURRENT_TIMESTAMP you can store date, it will be set at the creation date with hours (e.g: 2025-12-06 20:09:35) if you don't speficic one when you create a new instance.

string โ†’ VARCHAR(255) this is a tiny text field of up to 256 characters.

text โ†’ TEXT a large text (the maximum size depends on whether you are using PostgeSQL, MySQL/Mariadb or SQLite).

boolean โ†’ BOOLEAN simple true / false element.

โŽฏ ๐Ÿฅท And a secret field

You don't have to set it (and don't do it!) but there is a secret and default field inside each Model: id. This allows you to have a unique identifier for each instance of a Model. For example each time you will create a user, it will come with a unique identifier id, so you can find easily the user from its id.

const user = await User.create({username: "Goya"});
console.log(user.id)
// Print "1" if it's the first user

const user_by_id = await User.firstBy({id: user.id})
console.log(user.username == user_by_id.username)
// True

๐Ÿ› ๏ธ Methodsโ€‹

This methods are inherited from AModel.

โŽฏ ๐Ÿงฑ Constructor

Declaration:

/**
* Create an instance of the model
* with the fields provided
* @param {{}} fields
*/
constructor(fields)

Example:

// Create a new instance (you must use user.save())
// if you want to save it in the database
const user = new User({username: "Goya", email: "[email protected]"});

โŽฏ ๐Ÿ’พ To define database

Declaration:

/**
* Defines database to be used
* @param {ADriver} db
*/
static use(db)

Example:

// Define the database to be used by your model
User.use(clappybot.database);

โŽฏ โš™๏ธ To initialise database

Declaration:

/**
* Initialise the model's table,
* you should
*/
static async init()

Example:

// Initialise the table (this must be in your init.js)
User.init()

โŽฏ โœ… To save instance to the database

Declaration:

/**
* Save current instance in database
*/
async save()

Example:

// Create a new instance (not saved)
const user = new User({username: "Goya", email: "[email protected]"});
// Save it to the database
user.save();

โŽฏ โ™ป๏ธ Create and save at the same time

Declaration:

/**
* Create new instance of this model
* and save it in the database
* @param {{}} data
* @returns {Promise<AModel>}
*/
static async create(data = {})

Example:

// The "create" method creates the new element and saves it directly
const user = User.create({username: "LeWeeky", email: "[email protected]"});

โŽฏ ๐Ÿ—‘๏ธ Delete instance

Declaration:

/**
* Delete current instance from database
*/
async delete()

Example:

// The "create" method creates the new element and saves it directly
const user = User.create({username: "LeWeeky", email: "[email protected]"});
// Delete user thank's to the instance
await user.delete();

โŽฏ ๐Ÿงน Delete by fields

Declaration:

/**
* Deletes all elements that corresponding
* to the requested fields
* @param {{}} fields
*/
static async deleteBy(fields)

Example:

// All user with "LeWeeky" as their username AND "[email protected]" as
// their email will be deleted
await User.deleteBy({username: "LeWeeky", email: "[email protected]"});

โŽฏ ๐Ÿ—ƒ๏ธ Get all instances

Declaration:

/**
* Returns all elements of this table
* as new instances
*/
static async all()

Example:

// Get all users
const users = User.all()
// Print all users in the console
for (let i = 0; i < users.length; i++)
{
const user = users[i];
console.log(user.username, user)
}

โŽฏ ๐Ÿ”Ž Get all instances by fields

Declaration:

/**
* Returns all elements that corresponding
* to the requested fields as new instances
* @param {{}} fields
* @param {number} limit
* @returns {Promise<new() AModel[] | never[]>}
*/
static async findBy(fields, limit = 0)

Example:

// Get all users with "LeWeeky" as their username
const some_users = User.findBy({username: "LeWeeky"});
// Get 5 firsts users with "LeWeeky" as their username
const some_users = User.findBy({username: "LeWeeky"}, 5);

โŽฏ ๐Ÿ”Ž Get first instance by fields

Declaration:

/**
* Returns first element that corresponding
* to the requested fields as new instance
* @param {{}} fields
* @returns {Promise<AModel | null>}
*/
static async firstBy(fields)

Example:

// Get the first user from users with one or more specific fields
const leweeky = User.firstBy({username: "LeWeeky"});

โŽฏ ๐Ÿช„ First or Create

Declaration:

/**
* Returns first element that corresponding
* to the requested fields as new instance
* or create a new one if not found
* @param {{}} fields
* @returns {Promise<AModel>}
*/
static async firstByOrCreate(fields)

Example:

// Get the first user corresponding
// or create one if there are none
const leweeky = User.firstBy({username: "LeWeeky"});

โŽฏ ๐Ÿฅ‡ First

Declaration:

/**
* Returns first element as new instance
* @returns {Promise<AModel | null>}
*/
static async first()

Example:

// Get the first user
const user = User.first();

๐Ÿ†™ Update instance fieldsโ€‹

Maybe you want to change username of a specific user, you can do so as follow:

const user = await User.firstBy({id: 1});

user.username = "New username";
// Dont forget to save if you want to update it
// in your database
await user.save();