BaseModel API Reference
The BaseModel
class is the foundation of all models in Adonis ODM. It provides the core functionality for interacting with MongoDB documents.
Class Definition
abstract class BaseModel {
// Static properties
static table: string
static connection: string
static primaryKey: string
// Instance properties
$attributes: Record<string, any>
$original: Record<string, any>
$dirty: Record<string, any>
$isLocal: boolean
$isPersisted: boolean
$isDeleted: boolean
}
Static Properties
table
The MongoDB collection name for the model.
export default class User extends BaseModel {
static table = 'users'
}
Default: Pluralized, snake_case version of the model name
connection
The database connection to use for this model.
export default class User extends BaseModel {
static connection = 'mongodb'
}
Default: The default connection from config
primaryKey
The primary key field name.
export default class User extends BaseModel {
static primaryKey = '_id'
}
Default: '_id'
Static Methods
query(options?)
Create a new query builder instance.
static query(options?: QueryOptions): ModelQueryBuilder<Model>
Parameters:
options.client?
- Transaction client to use
Returns: ModelQueryBuilder<Model>
Example:
const users = await User.query().where('isActive', true).all()
create(attributes, options?)
Create and save a new model instance.
static async create<T extends BaseModel>(
this: ModelConstructor<T>,
attributes: Partial<ModelAttributes<T>>,
options?: SaveOptions
): Promise<T>
Parameters:
attributes
- The model attributesoptions.client?
- Transaction client to use
Returns: Promise<Model>
Example:
const user = await User.create({
name: 'John Doe',
email: '[email protected]'
})
createMany(attributesArray, options?)
Create multiple model instances.
static async createMany<T extends BaseModel>(
this: ModelConstructor<T>,
attributesArray: Partial<ModelAttributes<T>>[],
options?: SaveOptions
): Promise<T[]>
Example:
const users = await User.createMany([
{ name: 'John', email: '[email protected]' },
{ name: 'Jane', email: '[email protected]' }
])
find(id, options?)
Find a model by its primary key.
static async find<T extends BaseModel>(
this: ModelConstructor<T>,
id: any,
options?: QueryOptions
): Promise<T | null>
Example:
const user = await User.find('507f1f77bcf86cd799439011')
findOrFail(id, options?)
Find a model by its primary key or throw an exception.
static async findOrFail<T extends BaseModel>(
this: ModelConstructor<T>,
id: any,
options?: QueryOptions
): Promise<T>
Throws: ModelNotFoundException
if not found
findBy(field, value, options?)
Find a model by a specific field.
static async findBy<T extends BaseModel>(
this: ModelConstructor<T>,
field: string,
value: any,
options?: QueryOptions
): Promise<T | null>
Example:
const user = await User.findBy('email', '[email protected]')
findByOrFail(field, value, options?)
Find a model by a specific field or throw an exception.
static async findByOrFail<T extends BaseModel>(
this: ModelConstructor<T>,
field: string,
value: any,
options?: QueryOptions
): Promise<T>
first(options?)
Get the first model from the collection.
static async first<T extends BaseModel>(
this: ModelConstructor<T>,
options?: QueryOptions
): Promise<T | null>
firstOrFail(options?)
Get the first model from the collection or throw an exception.
static async firstOrFail<T extends BaseModel>(
this: ModelConstructor<T>,
options?: QueryOptions
): Promise<T>
all(options?)
Get all models from the collection.
static async all<T extends BaseModel>(
this: ModelConstructor<T>,
options?: QueryOptions
): Promise<T[]>
updateOrCreate(search, attributes, options?)
Update an existing model or create a new one.
static async updateOrCreate<T extends BaseModel>(
this: ModelConstructor<T>,
search: Partial<ModelAttributes<T>>,
attributes: Partial<ModelAttributes<T>>,
options?: SaveOptions
): Promise<T>
Example:
const user = await User.updateOrCreate(
{ email: '[email protected]' },
{ name: 'John Doe', isActive: true }
)
truncate(options?)
Remove all documents from the collection.
static async truncate<T extends BaseModel>(
this: ModelConstructor<T>,
options?: QueryOptions
): Promise<void>
Instance Properties
$attributes
The current model attributes.
readonly $attributes: Record<string, any>
$original
The original model attributes (before changes).
readonly $original: Record<string, any>
$dirty
The changed attributes since last save.
readonly $dirty: Record<string, any>
$isLocal
Whether the model exists only in memory (not saved to database).
readonly $isLocal: boolean
$isPersisted
Whether the model has been saved to the database.
readonly $isPersisted: boolean
$isDeleted
Whether the model has been deleted.
readonly $isDeleted: boolean
Instance Methods
save(options?)
Save the model to the database.
async save(options?: SaveOptions): Promise<this>
Parameters:
options.client?
- Transaction client to use
Example:
const user = new User()
user.name = 'John Doe'
user.email = '[email protected]'
await user.save()
delete(options?)
Delete the model from the database.
async delete(options?: QueryOptions): Promise<void>
refresh(options?)
Reload the model from the database.
async refresh(options?: QueryOptions): Promise<this>
fill(attributes)
Fill the model with attributes.
fill(attributes: Partial<ModelAttributes<this>>): this
Example:
const user = new User()
user.fill({
name: 'John Doe',
email: '[email protected]'
})
merge(attributes)
Merge attributes into the model.
merge(attributes: Partial<ModelAttributes<this>>): this
toJSON()
Convert the model to a plain JavaScript object.
toJSON(): Record<string, any>
serialize(cherryPick?)
Serialize the model with optional field selection.
serialize(cherryPick?: CherryPick): Record<string, any>
Parameters:
cherryPick.fields.pick?
- Fields to includecherryPick.fields.omit?
- Fields to exclude
Example:
// Include only specific fields
const json = user.serialize({
fields: {
pick: ['name', 'email']
}
})
// Exclude specific fields
const json = user.serialize({
fields: {
omit: ['password']
}
})
Hooks
Models support various lifecycle hooks:
@beforeSave()
Called before saving (create or update).
@beforeSave()
static async hashPassword(user: User) {
if (user.$dirty.password) {
user.password = await Hash.make(user.password)
}
}
@afterSave()
Called after saving (create or update).
@beforeCreate()
Called before creating a new model.
@afterCreate()
Called after creating a new model.
@beforeUpdate()
Called before updating an existing model.
@afterUpdate()
Called after updating an existing model.
@beforeDelete()
Called before deleting a model.
@afterDelete()
Called after deleting a model.
Types
ModelConstructor<T>
Type for model constructor.
type ModelConstructor<T extends BaseModel> = {
new (): T
// ... static methods
}
ModelAttributes<T>
Type for model attributes.
type ModelAttributes<T extends BaseModel> = {
[K in keyof T]: T[K]
}
SaveOptions
Options for save operations.
interface SaveOptions {
client?: TransactionClient
}
QueryOptions
Options for query operations.
interface QueryOptions {
client?: TransactionClient
}
CherryPick
Options for selective serialization.
interface CherryPick {
fields?: {
pick?: string[]
omit?: string[]
}
}
Examples
Basic CRUD Operations
// Create
const user = await User.create({
name: 'John Doe',
email: '[email protected]'
})
// Read
const foundUser = await User.find(user._id)
const userByEmail = await User.findBy('email', '[email protected]')
// Update
user.name = 'John Smith'
await user.save()
// Delete
await user.delete()
Working with Hooks
export default class User extends BaseModel {
@column()
declare email: string
@column()
declare password: string
@beforeSave()
static async normalizeEmail(user: User) {
if (user.$dirty.email) {
user.email = user.email.toLowerCase().trim()
}
}
@beforeCreate()
static async hashPassword(user: User) {
if (user.password) {
user.password = await Hash.make(user.password)
}
}
}
Custom Methods
export default class User extends BaseModel {
@column()
declare isActive: boolean
// Instance method
async activate() {
this.isActive = true
await this.save()
}
// Static method
static async getActiveUsers() {
return this.query().where('isActive', true).all()
}
}
Next Steps
- Query Builder API - Learn about building queries
- Embedded Documents - Work with nested data
- Database Manager - Manage connections and transactions