@megaorm/model v1.0.1
MegaORM Model
This package is designed to simplify database interactions in MegaORM
, providing a high-level API for seamless CRUD operations (INSERT
, SELECT
, UPDATE
, DELETE
). With support for:
- Complex queries
- Relationship management (
OneToOne
,OneToMany
,ManyToMany
) - Advanced features such as joins, pagination, and dynamic filtering, and more...
Table of Contents
- Installation
- Getting Started
- CRUD Operations
- Relationships
- Linking Models
- Modifiers
- Getter Methods
- Event Handling
Installation
To install this package, run the following command:
npm install @megaorm/model
You should be familiar with @megaorm/cli.
Getting Started
Creating Model Files
Use the following command to generate a new model file for your table:
node mega add:model <table>
To create a model for the users
table:
node mega add:model users
This will create a User.js
model file in ./models
(or User.ts
in ./src/models
if TypeScript is enabled).
Naming Conventions:
The model name is automatically generated as the singular form of your table name. Examples:
users
→User
profiles
→Profile
products
→Product
If the singular form cannot be resolved or you want a custom name, you can register a new singular/plural mapping in the MegaORM dictionary.
Customizing Model Names
To change the default singular form, add a mapping in your mega.js
file:
const { MegaCommand } = require('@megaorm/cli');
const { execute } = require('@megaorm/cli');
// Import dictionary
const { dictionary } = require('@megaorm-text');
// Register 'loser' as the singular form of 'users'
dictionary('loser', 'users');
// Execute commands
execute()
.then((message) => MegaCommand.success(message))
.catch((error) => MegaCommand.error(error.message))
.finally(() => process.exit());
Now, running the command:
node mega add:model users
Will create a Loser.js
model file instead of User.js
.
Model Files Template
Here’s what the generated User.js
file looks like:
const { MegaModel } = require('@megaorm/model');
class User extends MegaModel {
// The name of the table associated with this model
static table = 'users';
}
module.exports = { User };
You can now use the User
model to interact with the users
table and perform CRUD operations effortlessly.
Configuration Options
MegaModel
provides several static properties to configure your models:
Property | Description | Default |
---|---|---|
builder | Query builder instance | Required |
table | The associated database table name | Required |
timestamps | Automatically manage created_at and updated_at columns | true |
createdAt | Custom name for the created_at column | created_at |
updatedAt | Custom name for the updated_at column | updated_at |
primaryKey | Name of the primary key column | id |
foreignKey | Name of the foreign key column (e.g: user_id ) | <model>_id |
columns | Columns to select by default | All columns |
ignore | Columns to ignore during updates | Empty array |
modifiers | Modify model values after selection | Empty object |
const { MegaModel } = require('@megaorm/model');
class User extends MegaModel {
// The name of the table associated with this model
static table = 'users';
// Enable timestamps handling (default)
static timestamps = true;
// The users table createdAt column is `created_on`
static createdAt = 'created_on';
// The users table updatedAt column is `updated_on`
static updatedAt = 'updated_on';
// The users table primary key is id (default)
static primaryKey = 'id';
// The users table foreign key is user_id (default)
static foreignKey = 'user_id';
// The columns I want to select (default)
static columns = ['users.*'];
// The columns I want to ignore on update
static ignore = [User.primaryKey, User.createdAt];
}
module.exports = { User };
We will see how to use
modifiers
and how to set up yourbuilder
later
CRUD Operations
CRUD stands for Create, Read, Update, and Delete, and MegaModel
provides an easy way to perform these operations.
Create Users
insert(row)
and insertMany(rows)
allow you to insert one or more rows into the database.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// Insert One User
const user = await User.insert({
email: 'user1@gmail.com',
password: '123',
});
console.log(user instanceof User); // true
console.log(user); // { id: 1, email: 'user1@gmail.com', ... }
// Insert Many Users
const users = await User.insertMany([
{
email: 'user2@gmail.com',
password: '123',
},
{
email: 'user3@gmail.com',
password: '123',
},
]);
console.log(users.every((user) => user instanceof User)); // true
console.log(users); // [{ email: 'user2@gmail.com', ... }, ...]
// Release the connection
connection.release();
};
// Execute
app();
Notes for
insert(row)
:- For all drivers: The resolved model instances will include their primary keys.
- Emits an
INSERT
event before the row is inserted andINSERTED
event after. - If
User.timestamps
is true, thecreated_at
andupdated_at
columns will be set automatically.
Notes for
insertMany(rows)
:- For
PostgreSQL
: The resolved model instances include their primary keys. - For
MySQL
&SQLite
: The resolved model instances do not include primary keys. - Emits an
INSERT_MANY
event before the rows are inserted andINSERTED_MANY
event after. - If
User.timestamps
is true, thecreated_at
andupdated_at
columns will be set automatically.
- For
Read Users
find(key)
and findMany(keys)
allow you to retrieve one or more models by their primary keys.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// Find the user where id = 1
console.log(await User.find(1));
// Resolves with a User instance
// or undefined if no matching User is found
// Find users where id is in [1, 3, 5, 7]
console.log(await User.findMany(1, 3, 5, 7));
// Resolves with an array of User instances
// or an empty array if no matches are found
// Release the connection
connection.release();
};
// Execute
app();
The primary key does not have to be a
number
; it can be any value that uniquely identifies a record, such asemails
,UUIDs
, or other custom unique identifiers.
select()
returns a Selector
instance, which you can use to build and execute a SELECT
query. The key difference between Selector
and Select
is in the exec
method:
- The
exec
method inSelect
resolves with an array of rows (anonymous objects). - The
exec
method inSelector
resolves with an array ofMegaModel
instances.
In Selector
, you can also use the all()
method to execute your queries.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder, ref } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// Get all users
console.log(await User.select().all());
// Get users with their profiles using an inner join
console.log(
await User.select()
.col('users.*', 'profiles.age', 'profiles.gender')
.join('profiles', (col) => {
col('users.id').equal(ref('profiles.user_id'));
})
.exec()
); // Array of User models with associated profile data
// Release the connection
connection.release();
};
// Execute
app();
You can chain additional methods on the Selector
instance to refine your query, such as .where()
, .groupBy()
, .orderBy()
, and .limit()
. The API is identical to the Select
provided by @megaorm/builder.
Columns and tables are automatically set based on the model configuration.
Update Users
The update()
method updates the record associated with the current instance using the model's primary key.
Additionally, it automatically updates the updatedAt
timestamp if timestamp handling is enabled.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// First, find the user you want to update
const user = await User.find(1);
// Update the user's properties
user.email = 'updated@gmail.com';
user.password = 'updated123';
// Save the changes
await user.update();
// If you have the primary key of the user!
// You can do this instead:
const secondUser = new User({ id: 2 });
secondUser.email = 'updated2@gmail.com';
secondUser.password = 'updated456';
// Save the changes
await secondUser.update();
// Release the connection
connection.release();
};
// Execute
app();
The
update()
method triggers theUPDATE
event before the update and theUPDATED
event after the update.
Delete Users
The delete()
method deletes the record associated with the current instance using the model's primary key.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// First, find the user you want to delete
const user = await User.find(1);
// Delete the user
await user.delete();
// If you have the primary key of the user!
// You can do this instead:
await new User({ id: 3 }).delete();
// Release the connection
connection.release();
};
// Execute
app();
The
delete()
method triggers theDELETE
event before the deletion and theDELETED
event after the deletion.
Where RUD (Read, Update, Delete)
where(condition)
allows you to build and execute SELECT
, UPDATE
, and DELETE
queries based on specific conditions.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// Select a user with a specific ID
await User.where((col) => col('id').equal(20)).select();
// Delete a user with a specific ID
await User.where((col) => col('id').equal(30)).delete();
// Update a user's information by ID
await User.where((col) => col('id').equal(45)).update({
email: 'updated@gmail.com',
});
// Release the connection
connection.release();
};
// Execute
app();
This method does not emit any events, unlink
insert
,insertMany
,update
anddelete
.
Relationships
MegaModel provides built-in methods to simplify loading related models. with support for common relationships like OneToOne, OneToMany, and ManyToMany. You might already be familiar with these concepts, but even if you're not, this guide should be sufficient to get you started.
OneToOne Relationship
Imagine we have a User
model and a Profile
model. Each user has exactly one profile, representing a OneToOne relationship. Here's how you can load the profile of any user:
// Import modules
const { MegaModel } = require('@megaorm/model');
const { Profile } = require('./models/Profile');
// In your User.js file
class User extends MegaModel {
// Set the table name
static table = 'users';
// This property will store the profile data
profile;
// Define a method to load the user's profile
loadProfile() {
return new Promise((resolve, reject) => {
// Check if the profile is already loaded
if (this.profile) return resolve(this.profile);
// Fetch the profile using the OneToOne method
this.OneToOne(Profile)
.then((profile) => {
this.profile = profile; // Cache the profile
resolve(profile); // Resolve with the fetched profile
})
.catch(reject); // Reject if there's an error
});
}
}
To use this method to load any user's profile, follow the steps below:
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the User model
User.builder = builder;
// Fetch the first user
const user = await User.find(1);
// Load the user's profile
await user.loadProfile();
// The profile is now cached on the User instance
console.log(user.profile);
// Release the connection
connection.release();
};
// Execute
app();
OneToOne Reverse Relationship
You can also load the user associated with a profile using the References(model)
method. This is the reverse of the OneToOne relationship.
// Import modules
const { MegaModel } = require('@megaorm/model');
const { User } = require('./models/User');
// In your Profile.js file
class Profile extends MegaModel {
// Set the table name
static table = 'profiles';
// This property will store the user data
user;
// Define a method to load the user of the profile
loadUser() {
return new Promise((resolve, reject) => {
// Check if the user is already loaded
if (this.user) return resolve(this.user);
// Fetch the user using the References method
this.References(User)
.then((user) => {
this.user = user; // Cache the user
resolve(user); // Resolve with the fetched user
})
.catch(reject); // Reject if there's an error
});
}
}
Here's how you can load the user for any profile:
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { Profile } = require('./models/Profile');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the Profile model
Profile.builder = builder;
// Fetch the first profile
const profile = await Profile.find(1);
// Load the user of the profile
await profile.loadUser();
// The user is now cached on the Profile instance
console.log(profile.user);
// Release the connection
connection.release();
};
// Execute
app();
- Use
OneToOne(model)
to load the child model (e.g., a user loads their profile). - Use
References(model)
to load the parent model (e.g., a profile loads its user). - The child model typically has a foreign key referencing the parent model.
- Both
OneToOne(model)
andReferences(model)
will throw an error if multiple related models are found, as this violates theOneToOne
relationship. They returnundefined
if no related model is found. - In a
OneToOne
relationship, each instance of the parent model should correspond to exactly one instance of the child model (e.g., each user has exactly one profile).
OneToMany Relationship
In a OneToMany relationship, one record in a parent model is associated with multiple records in a child model. For example, a User
can have multiple Post
records.
To demonstrate, let’s say we have a User
model and a Post
model. Each Post
references a User
(the parent model) via a foreign key (user_id
). Using MegaORM, you can load all posts associated with a user as shown below:
// Import modules
const { MegaModel } = require('@megaorm/model');
const { Post } = require('./models/Post');
// In your User.js file
class User extends MegaModel {
// Set the table name
static table = 'users';
// This property will store the user's posts
posts;
// Define a method to load the user's posts
loadPosts() {
return new Promise((resolve, reject) => {
// Check if posts are already loaded and resolve from cache
if (this.posts) return resolve(this.posts);
// Fetch posts using the OneToMany method
this.OneToMany(Post)
.then((posts) => {
this.posts = posts; // Cache the posts
resolve(posts); // Resolve with the fetched posts
})
.catch(reject); // Reject if there's an error fetching posts
});
}
}
In your main application file (index.js
), you can use the loadPosts
method to load the posts for any user instance:
// Import MegaConfig, MegaBuilder, and the User model
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { User } = require('./models/User');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the query builder for the User model
User.builder = builder;
// Retrieve the first user
const user = await User.find(1);
// Load the user's posts
await user.loadPosts();
// The posts are now cached on the User instance
console.log(user.posts);
// Release the connection
connection.release();
};
// Execute
app();
OneToMany Reverse Relationship
Each Post
references a User
, making it easy to navigate back to the parent model. To load the User
associated with a Post
, use the References
method:
// Import the User model
const { User } = require('./models/User');
// In your Post.js file
class Post extends MegaModel {
// Set the table name
static table = 'posts';
// This property will store the user data
user;
// Define a method to load the user of the post
loadUser() {
return new Promise((resolve, reject) => {
// Check if the user is already loaded
if (this.user) return resolve(this.user);
// Fetch the user using the References method
this.References(User)
.then((user) => {
this.user = user; // Cache the user
resolve(user); // Resolve with the fetched user
})
.catch(reject); // Reject if there's an error
});
}
}
You can now load the user of any post by simply executing the
loadUser()
method.
ManyToMany Relationship
Consider a scenario where we have a Post
model and a Category
model. Each post can have many categories, and each category can have many posts (ManyToMany relationship). In this case, we can load the posts of a category and the categories of a post using the following approach.
// Import modules
const { MegaModel } = require('@megaorm/model');
const { Category } = require('./models/Category');
// In your Post.js file
class Post extends MegaModel {
// Set the table name
static table = 'posts';
// This property will store the categories
categories;
// Define a method to load the post's categories
loadCategories() {
return new Promise((resolve, reject) => {
// Check if categories are already loaded
if (this.categories) return resolve(this.categories);
// Fetch categories using the ManyToMany method
this.ManyToMany(Category)
.then((categories) => {
this.categories = categories; // Cache the categories
resolve(categories); // Resolve with the fetched categories
})
.catch(reject); // Reject if there's an error
});
}
}
Next, you should define another method in the Category
model to load all posts associated with a specific category.
// Import modules
const { MegaModel } = require('@megaorm/model');
const { Post } = require('./models/Post');
// In your Category.js file
class Category extends MegaModel {
// Set the table name
static table = 'categories';
// This property will store the posts
posts;
// Define a method to load the category's posts
loadPosts() {
return new Promise((resolve, reject) => {
// Check if posts are already loaded
if (this.posts) return resolve(this.posts);
// Fetch posts using the ManyToMany method
this.ManyToMany(Post)
.then((posts) => {
this.posts = posts; // Cache the posts
resolve(posts); // Resolve with the fetched posts
})
.catch(reject); // Reject if there's an error
});
}
}
Finally, in your index.js
, you can use these methods to load the posts of any category and the categories of any post.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { Post } = require('./models/Post');
const { Category } = require('./models/Category');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set the builder for the Post and Category models
Post.builder = builder;
Category.builder = builder;
// Get the first post and category
const post = await Post.find(1);
const category = await Category.find(1);
// Load the post's categories
await post.loadCategories();
// Load the category's posts
await category.loadPosts();
// Posts are now cached on the Category instance
console.log(category.posts);
// Categories are now cached on the Post instance
console.log(post.categories);
// Release the connection
connection.release();
};
// Execute
app();
This method assumes a
ManyToMany
relationship, where a link table (e.g.,category_post
) connects the parent model (Post
) and the child model (Category
).Optionally, you can specify the name of the link table as the second argument in
ManyToMany(model, table?)
. If not provided, the default table name is generated by combining the parent and child model names alphabetically.You can also specify the columns you want to retrieve from the link table as the third argument in
ManyToMany(model, table?, ...columns)
. Although it is not recommended to have other columns in the link table besides foreign keys, you can include additional columns if needed, and they will be included in the result.
Linking Models
In addition to fetching related models, you can easily link and unlink models to create or remove ManyToMany
relationships.
What is Linking?
In a ManyToMany
relationship, a row in one table can be associated with multiple rows in another table. For example, a post can belong to multiple categories, and each category can have multiple posts. To manage these relationships, we use three tables:
posts
: stores post datacategories
: stores category datacategory_post
: the link table connecting posts and categories
Link Methods
link(model, table?, row?)
: Creates a link between the current model and the provided model by inserting a record into the link table.linkMany(models, table?, rows?)
: Creates links between the current model and multiple models by inserting multiple records into the link table.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { Post } = require('./models/Post');
const { Category } = require('./models/Category');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set builder for models
Post.builder = builder;
Category.builder = builder;
// Fetch the post and category
const post = await Post.find(1);
const category = await Category.find(1);
// Link post to category
await post.link(category);
// Link post to multiple categories
const categories = await Category.findMany(2, 3, 4);
await post.linkMany(categories);
// Now the post is linked with 4 categories
console.log(await post.loadCategories());
// Release the connection
connection.release();
};
// Execute
app();
- You can pass extra columns in the third argument, besides the foreign keys.
link
emitsLINK
before andLINKED
after the link is created.linkMany
emitsLINK_MANY
before andLINKED_MANY
after creating multiple links.
Unlink Methods
In addition to linking models, you can also unlink models in a ManyToMany relationship. This is done with the following methods:
unlink(model, table?)
: Removes a link between the current model and the provided model by deleting the corresponding record from the link table.unlinkMany(models, table?)
: Removes links between the current model and multiple models by deleting multiple records from the link table.
// Import modules
const { MegaConfig } = require('@megaorm/cli');
const { MegaBuilder } = require('@megaorm/builder');
const { Post } = require('./models/Post');
const { Category } = require('./models/Category');
const app = async () => {
// Load config and create builder
const config = await MegaConfig.load();
const connection = await config.cluster.request(config.default);
const builder = new MegaBuilder(connection);
// Set builder for models
Post.builder = builder;
Category.builder = builder;
// Fetch the post and category
const post = await Post.find(1);
const category = await Category.find(1);
// Unlink the post from the category
await post.unlink(category);
// Unlink post from multiple categories
const categories = await Category.findMany(2, 3, 4);
await post.unlinkMany(categories);
// Now the post has no categories
console.log(await post.loadCategories());
// Release the connection
connection.release();
};
// Execute
app();
unlink
emits theUNLINK
event before the unlink and theUNLINKED
event after the unlink.unlinkMany
emits theUNLINK_MANY
event before andUNLINKED_MANY
event after unlinking multiple models.- You can specify the link table name in the second argument if you don't follow MegaORM's default link table naming convention.
Modifiers
Modifiers in MegaORM let you apply transformations to column values when they are fetched from the database. You can register these modifiers for specific columns to ensure that data is always formatted the way you want.
Format Post Title
If you want to ensure that the title
of every post is formatted correctly (e.g., capitalizing the first letter of each word), you can create a modifier function like this:
// Modifier function to format title
function formatTitle(title) {
return title
.trim()
.toLowerCase()
.split(' ')
.map((word) => word[0].toUpperCase() + word.slice(1))
.join(' ');
}
// In your Post model
class Post extends MegaModel {
static table = 'posts';
// Register modifier for the 'title' column
static modifiers = {
title: [formatTitle],
};
}
How It Works:
- When you fetch posts, the
title
field will be automatically transformed by theformatTitle
function. - For example, a title like
" i love megaorm "
will become"I Love Megaorm"
.
Getter Methods
MegaModel offers several useful getter methods that help you interact with your model's configuration and manage its state. These methods are particularly useful when extending MegaModel or accessing model properties dynamically.
Method | Description |
---|---|
get.builder() | Returns the MegaBuilder instance for the model. |
get.table() | Returns the model's table name. |
get.columns() | Returns the model's selected columns. |
get.ignore() | Returns columns ignored during updates. |
get.createdAt() | Returns the created_at column name. |
get.updatedAt() | Returns the updated_at column name. |
get.timestamps() | Indicates if timestamp support is enabled. |
get.link(model) | Returns the link table name for ManyToMany relationships. |
get.emitter() | Returns the model's EventEmitter instance. |
get.modifiers(column) | Returns modifiers for a specific column. |
model() | Returns the model class from an instance. |
valueOf(column) | Returns the value of a column, ensuring it's defined. |
Event Handling
These events define the lifecycle of various operations. Each operation emits specific events to allow for hooks or listeners that can execute additional logic before or after the operation. Here's a breakdown:
Insert Events
INSERT
- Emitted before a single row is inserted.
- Parameter:
row
- The row data to be inserted. - Triggered by the
insert()
static method.
INSERTED
- Emitted after a single row is inserted.
- Parameter:
model
- The resulting model from the insert operation. - Triggered by the
insert()
static method.
INSERT_MANY
- Emitted before multiple rows are inserted.
- Parameter:
rows
- The rows data to be inserted. - Triggered by the
insertMany()
static method.
INSERTED_MANY
- Emitted after multiple rows are inserted.
- Parameter:
models
- The resulting models from the insert operation. - Triggered by the
insertMany()
static method.
Update Events
UPDATE
- Emitted before a model is updated.
- Parameter:
model
- The model to be updated. - Triggered by the
update()
method.
UPDATED
- Emitted after a model is updated.
- Parameter:
model
- The updated model. - Triggered by the
update()
method.
Delete Events
DELETE
- Emitted before a model is deleted.
- Parameter:
model
- The model to be deleted. - Triggered by the
delete()
method.
DELETED
- Emitted after a model is deleted.
- Parameter:
model
- The deleted model. - Triggered by the
delete()
method.
Linking Events
Linking connects models in a link table. learn more here....
LINK
- Emitted before linking one model to another.
- Parameters:
main
: The model being linked.model
: The target model.data
: Additional data for the link operation.
- Triggered by the
link()
method.
LINKED
- Emitted after linking one model to another.
- Same parameters as
LINK
. - Triggered by the
link()
method.
LINK_MANY
- Emitted before linking multiple models to another.
- Parameters:
main
: The model being linked.models
: The target models.data
: Additional data for the link operation.
- Triggered by the
linkMany()
method.
LINKED_MANY
- Emitted after linking multiple models to another.
- Same parameters as
LINK_MANY
. - Triggered by the
linkMany()
method.
Unlinking Events
Unlinking removes connection between models from the link table. learn more here....
UNLINK
- Emitted before unlinking one model from another.
- Parameters:
main
: The model being unlinked.model
: The target model.
- Triggered by the
unlink()
method.
UNLINKED
- Emitted after unlinking one model from another.
- Same parameters as
UNLINK
. - Triggered by the
unlink()
method.
UNLINK_MANY
- Emitted before unlinking multiple models from another.
- Parameters:
main
: The model being unlinked.models
: The target models.
- Triggered by the
unlinkMany()
method.
UNLINKED_MANY
- Emitted after unlinking multiple models from another.
- Same parameters as
UNLINK_MANY
. - Triggered by the
unlinkMany()
method.
Usage Example
// Import INSERT event
const { INSERT } = require('@megaorm/model');
const { UPDATE } = require('@megaorm/model');
const { DELETE } = require('@megaorm/model');
// Import toSlug
const { toSlug } = require('@megaorm/text');
// Import UTC
const { UTC } = require('@megaorm/utc');
// In your Post.js file
class Post extends MegaModel {
static table = 'posts';
}
// Example 1: Prepare the row for insert
Post.get.emitter().on(INSERT, (row) => {
// Here you can update the row before insert
row.title.toLowerCase();
row.slug = toSlug(row.title); // create a slug from title
// You can also handle timestamps your self
row.created_at = UTC.get.datetime(); // Creation datetime in UTC
row.updated_at = null; // Set null
});
// Example 2: Prepare row for UPDATE
Post.get.emitter().on(UPDATE, (row) => {
// Update the slug using the new title
row.slug = toSlug(row.title);
// Set updated_at
row.update_at = UTC.get.datetime();
});
// Example 3: Prepare a model for DELETE
Post.get.emitter().on(DELETE, (post) => {
// Perform any cleanup actions
if (post.is_published) {
throw new Error('Cannot delete a published post.');
}
});
You can also use the
INSERT
event to validate user inputs before insertion.