ایجاد کلاس مدل جدید
این راهنما نحوه ایجاد یک کلاس مدل جدید در فریمورک کیمیا را توضیح میدهد.
پیشنیازها
قبل از شروع، اطمینان حاصل کنید که:
- یک اپلیکیشن کیمیا دارید (به راهنمای ایجاد اپلیکیشن جدید مراجعه کنید)
- با ساختار پایه مدلها و Sequelize آشنا هستید
- رابط TypeScript مدل را تعریف کردهاید
ساختار کلاس مدل
کلاس پایه (Base Class)
هر کلاس مدل باید از کلاس Model کتابخانه Sequelize ارثبری کند:
import { Model } from 'sequelize';
import { MyModelInterface } from '../interfaces';
export class MyModel extends Model<MyModelInterface> { }
تابع load
هر مدل باید دارای یک تابع load باشد که مدل را مقداردهی اولیه میکند:
import { DataTypes, Model } from 'sequelize';
import { Global } from '@core/global';
import { MyModelInterface } from '../interfaces';
export class MyModel extends Model<MyModelInterface> { }
export function load() {
return MyModel.init({
// ویژگیهای مدل اینجا تعریف میشوند
id: {
type: DataTypes.BIGINT,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
// سایر فیلدها...
}, {
sequelize: Global.Database.dbConn,
modelName: 'MyModel',
tableName: 'my_models',
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
paranoid: true, // برای soft delete
});
}
تعریف ویژگیهای مدل
انواع دادهها
از انواع دادههای Sequelize استفاده کنید:
import { DataTypes } from 'sequelize';
// انواع پایه
DataTypes.STRING // رشته متنی
DataTypes.TEXT // متن طولانی
DataTypes.INTEGER // عدد صحیح
DataTypes.BIGINT // عدد صحیح بزرگ
DataTypes.FLOAT // عدد اعشاری
DataTypes.DOUBLE // عدد اعشاری دوگانه
DataTypes.DECIMAL // عدد اعشاری دقیق
DataTypes.BOOLEAN // بولین
DataTypes.DATE // تاریخ
DataTypes.DATE(6) // تاریخ با میکروثانیه
DataTypes.JSON // داده JSON
DataTypes.UUID // UUID
گزینههای فیلد
هر فیلد میتواند گزینههای مختلفی داشته باشد:
{
type: DataTypes.STRING, // نوع داده
allowNull: false, // اجباری بودن
defaultValue: 'default', // مقدار پیشفرض
unique: true, // یکتا بودن
primaryKey: true, // کلید اصلی
autoIncrement: true, // افزایش خودکار
comment: 'توضیح فیلد', // کامنت
}
گزینههای مدل
گزینههای پایه
{
sequelize: Global.Database.dbConn, // اتصال دیتابیس
modelName: 'MyModel', // نام مدل
tableName: 'my_models', // نام جدول
timestamps: true, // فعال بودن timestamps
createdAt: 'created_at', // نام فیلد created_at
updatedAt: 'updated_at', // نام فیلد updated_at
deletedAt: 'deleted_at', // نام فیلد deleted_at
paranoid: true, // فعال بودن soft delete
}
گزینههای پیشرفته
{
// ایندکسها
indexes: [
{
unique: true,
fields: ['email', 'username']
}
],
// هوکها (Hooks)
hooks: {
beforeCreate: (instance) => {
// کد قبل از ایجاد
},
afterUpdate: (instance) => {
// کد بعد از بروزرسانی
}
},
// اسکوپها (Scopes)
scopes: {
active: {
where: { status: 'active' }
}
}
}
تعریف رابط TypeScript
رابط مدل بهتر است در فایل app/interfaces/models/ تعریف شود:
// app/interfaces/models/MyModel.ts
export interface MyModelInterface {
id?: number;
name: string;
description?: string;
status?: 'active' | 'inactive';
created_at?: number;
updated_at?: number;
deleted_at?: number;
}
ثبت مدل
مدلهای اپلیکیشن
مدلهای اپلیکیشن در فایل app/models/models.ts ثبت میشوند:
import { ModelDefinition } from "@core/server/interfaces";
import { MyModel } from './MyModel';
export type AppModelName =
| "MyModel";
export const AppModels: ModelDefinition<AppModelName>[] = [
{ name: "MyModel", class: MyModel },
];
مدلهای هسته
مدلهای هسته در فایل core/database/models/index.ts ثبت میشوند و در تنظیمات INIT_MODELS اضافه میشوند.
مثال کامل
1. تعریف رابط
// app/interfaces/models/Product.ts
export interface ProductModel {
id?: number;
name: string;
description?: string;
price: number;
category_id?: number;
status: 'active' | 'inactive';
created_at?: number;
updated_at?: number;
deleted_at?: number;
}
2. ایجاد کلاس مدل
// app/models/Product.ts
import { Model, DataTypes } from 'sequelize';
import { Global } from '@core/global';
import { ProductModel } from '../interfaces/models/Product';
export class Product extends Model<ProductModel> { }
export function load() {
return Product.init({
id: {
type: DataTypes.BIGINT,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING(255),
allowNull: false,
comment: 'نام محصول',
},
description: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'توضیح محصول',
},
price: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
defaultValue: 0,
comment: 'قیمت محصول',
},
category_id: {
type: DataTypes.BIGINT,
allowNull: true,
comment: 'شناسه دستهبندی',
},
status: {
type: DataTypes.ENUM('active', 'inactive'),
allowNull: false,
defaultValue: 'active',
comment: 'وضعیت محصول',
},
created_at: DataTypes.DATE(6),
updated_at: DataTypes.DATE(6),
deleted_at: DataTypes.DATE(6),
}, {
sequelize: Global.Database.dbConn,
modelName: 'Product',
tableName: 'products',
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
paranoid: true,
indexes: [
{
fields: ['category_id'],
},
{
fields: ['status'],
},
],
});
}
3. ثبت مدل
import { ModelDefinition } from "@core/server/interfaces";
import { Product } from './Product';
export type AppModelName =
| "Product";
export const AppModels: ModelDefinition<AppModelName>[] = [
{ name: "Product", class: Product },
];
استفاده از مدل
عملیات پایه
import { Product } from './Product';
// ایجاد رکورد جدید
const product = await Product.create({
name: 'محصول نمونه',
price: 100000,
status: 'active',
});
// جستجو
const products = await Product.findAll({
where: { status: 'active' },
limit: 10,
});
// جستجو با ID
const product = await Product.findByPk(1);
// بروزرسانی
await product.update({ price: 150000 });
// حذف (soft delete اگر paranoid فعال باشد)
await product.destroy();
عملیات پیشرفته
// جستجو با شرایط پیچیده
const products = await Product.findAll({
where: {
price: { [Op.gte]: 50000 },
status: 'active',
},
include: [
{ model: Category, as: 'category' }
],
order: [['created_at', 'DESC']],
limit: 20,
offset: 0,
});
// شمارش رکوردها
const count = await Product.count({
where: { status: 'active' }
});
// بروزرسانی گروهی
await Product.update(
{ status: 'inactive' },
{ where: { category_id: 5 } }
);
نکات مهم
- نام جدول بهتر است جمع و با حروف کوچک باشد
- بهتر است از
DataTypes.DATE(6)برای فیلدهای تاریخ استفاده کنید - از
paranoid: trueبرای soft delete استفاده کنید - فیلدهای اجباری را با
allowNull: falseتعریف کنید - از کامنتها برای توضیح فیلدها استفاده کنید
- ایندکسها را برای فیلدهای جستجو شده تعریف کنید
توسعه بیشتر
پس از ایجاد کلاس مدل پایه، میتوانید:
- هوکها و اسکوپهای سفارشی اضافه کنید
- متدهای استاتیک و نمونه برای عملیات خاص پیادهسازی کنید