Individual database records with complete CRUD operations, attribute management, query building, and relationship definitions.
Create model instances using the constructor or static forge method.
/**
* Model constructor
* @param {object} [attributes] - Initial attribute values
* @param {object} [options] - Configuration options
* @param {string} [options.tableName] - Override table name
* @param {boolean|Array} [options.hasTimestamps] - Enable timestamp columns
* @param {boolean} [options.parse] - Parse attributes on construction
* @param {Array} [options.visible] - Visible attributes for serialization
* @param {Array} [options.hidden] - Hidden attributes for serialization
* @param {boolean} [options.requireFetch] - Require explicit fetch before save/destroy
*/
new Model(attributes?: object, options?: object);
/**
* Create model instance without 'new' keyword
* @param {object} [attributes] - Initial attribute values
* @param {object} [options] - Configuration options
* @returns {Model} New model instance
*/
Model.forge(attributes?: object, options?: object): Model;Usage Examples:
// Using constructor
const user = new User({name: 'Alice', email: 'alice@example.com'});
// Using forge
const user = User.forge({name: 'Bob', email: 'bob@example.com'});
// With options
const user = User.forge({name: 'Charlie'}, {
hasTimestamps: true,
visible: ['name', 'email'],
hidden: ['password']
});Core properties for model configuration and state.
interface ModelProperties {
/** Database table name (required) */
tableName: string;
/** Primary key column name (default: 'id') */
idAttribute: string;
/** Enable automatic timestamp columns */
hasTimestamps: boolean | Array<string>;
/** Default attribute values */
defaults: object;
/** Attributes to hide during serialization */
hidden: Array<string>;
/** Attributes to show during serialization (overrides hidden) */
visible: Array<string>;
/** Require explicit fetch before save/destroy operations */
requireFetch: boolean;
/** Current attribute values */
attributes: object;
/** Changed attributes since last save */
changed: object;
/** Loaded relationship data */
relations: object;
/** Primary key value */
id: any;
/** Client-side unique identifier */
cid: string;
}Class-level methods for querying without instantiation.
/**
* Create collection of this model type
* @param {Model[]} [models] - Initial models for collection
* @param {object} [options] - Collection options
* @returns {Collection} New collection instance
*/
Model.collection(models?: Model[], options?: object): Collection;
/**
* Count records matching current query
* @param {string} [column='*'] - Column to count
* @param {object} [options] - Query options
* @returns {Promise<number>} Record count
*/
Model.count(column?: string, options?: object): Promise<number>;
/**
* Fetch all records as collection
* @param {object} [options] - Fetch options
* @returns {Promise<Collection>} Collection of all records
*/
Model.fetchAll(options?: object): Promise<Collection>;
/**
* Fetch paginated results
* @param {object} [options] - Pagination options
* @param {number} [options.page=1] - Page number
* @param {number} [options.pageSize=10] - Items per page
* @returns {Promise<{models: Collection, pagination: object}>} Paginated results
*/
Model.fetchPage(options?: object): Promise<{models: Collection, pagination: object}>;
/**
* Add where clause and return query instance
* @param {...*} args - Where clause arguments
* @returns {Model} Query instance for chaining
*/
Model.where(...args: any[]): Model;
/**
* Access underlying query builder
* @param {...*} args - Query builder arguments
* @returns {Model} Query instance for chaining
*/
Model.query(...args: any[]): Model;Core database operations for fetching, saving, and deleting records.
/**
* Fetch model from database
* @param {object} [options] - Fetch options
* @param {string[]} [options.withRelated] - Relations to eager load
* @param {string} [options.require=false] - Throw if not found
* @param {object} [options.transacting] - Transaction object
* @returns {Promise<Model>} Fetched model
*/
fetch(options?: {
withRelated?: string[],
require?: boolean,
transacting?: Transaction,
columns?: string[],
debug?: boolean
}): Promise<Model>;
/**
* Save model to database
* @param {string|object} [key] - Attribute name or attributes object
* @param {*} [value] - Attribute value (if key is string)
* @param {object} [options] - Save options
* @returns {Promise<Model>} Saved model
*/
save(key?: string | object, value?: any, options?: {
method?: 'insert' | 'update',
defaults?: object,
patch?: boolean,
transacting?: Transaction,
debug?: boolean
}): Promise<Model>;
/**
* Delete model from database
* @param {object} [options] - Delete options
* @returns {Promise<Model>} Deleted model
*/
destroy(options?: {
require?: boolean,
transacting?: Transaction,
debug?: boolean
}): Promise<Model>;
/**
* Load specific relations after initial fetch
* @param {string|string[]} relations - Relation names to load
* @param {object} [options] - Load options
* @returns {Promise<Model>} Model with loaded relations
*/
load(relations: string | string[], options?: object): Promise<Model>;Usage Examples:
// Fetch with relations
const user = await new User({id: 1}).fetch({
withRelated: ['posts', 'profile'],
require: true
});
// Save new record
const user = await new User({name: 'Alice', email: 'alice@example.com'}).save();
// Update existing record
await user.save({name: 'Alice Smith'});
// Delete record
await user.destroy();
// Load relations after fetch
await user.load(['posts.comments', 'profile']);Methods for getting, setting, and manipulating model attributes.
/**
* Get attribute value
* @param {string} attribute - Attribute name
* @returns {*} Attribute value
*/
get(attribute: string): any;
/**
* Set attribute value(s)
* @param {string|object} key - Attribute name or attributes object
* @param {*} [value] - Attribute value (if key is string)
* @param {object} [options] - Set options
* @returns {Model} Model instance for chaining
*/
set(key: string | object, value?: any, options?: {
unset?: boolean,
silent?: boolean
}): Model;
/**
* Check if attribute exists and is not null/undefined
* @param {string} attribute - Attribute name
* @returns {boolean} True if attribute exists
*/
has(attribute: string): boolean;
/**
* Remove specific attribute
* @param {string} attribute - Attribute name to remove
* @param {object} [options] - Unset options
* @returns {Model} Model instance for chaining
*/
unset(attribute: string, options?: object): Model;
/**
* Clear all attributes
* @param {object} [options] - Clear options
* @returns {Model} Model instance for chaining
*/
clear(options?: object): Model;
/**
* Get escaped attribute value for SQL
* @param {string} attribute - Attribute name
* @returns {string} Escaped attribute value
*/
escape(attribute: string): string;
/**
* Get subset of attributes
* @param {...string} attributes - Attribute names to include
* @returns {object} Object with specified attributes
*/
pick(...attributes: string[]): object;
/**
* Get attributes excluding specified ones
* @param {...string} attributes - Attribute names to exclude
* @returns {object} Object without specified attributes
*/
omit(...attributes: string[]): object;Methods for checking model state and changes.
/**
* Check if model is new (not persisted to database)
* @returns {boolean} True if model is new
*/
isNew(): boolean;
/**
* Check if attributes have changed since last fetch/save
* @param {string} [attribute] - Specific attribute to check
* @returns {boolean} True if changed
*/
hasChanged(attribute?: string): boolean;
/**
* Get hash of changed attributes
* @returns {object} Object containing changed attributes
*/
changed(): object;
/**
* Get previous attribute value(s)
* @param {string} [attribute] - Specific attribute
* @returns {*|object} Previous value or all previous values
*/
previous(attribute?: string): any;
/**
* Get all previous attributes
* @returns {object} Previous attributes object
*/
previousAttributes(): object;Methods for converting models to JSON and handling data formatting.
/**
* Convert model to JSON object
* @param {object} [options] - Serialization options
* @returns {object} JSON representation
*/
toJSON(options?: {
shallow?: boolean,
omitPivot?: boolean
}): object;
/**
* Serialize model and relations
* @param {object} [options] - Serialization options
* @returns {object} Serialized model data
*/
serialize(options?: object): object;
/**
* Parse attributes from database
* @param {object} attributes - Raw database attributes
* @param {object} [options] - Parse options
* @returns {object} Parsed attributes
*/
parse(attributes: object, options?: object): object;
/**
* Format attributes for database
* @param {object} attributes - Model attributes
* @param {object} [options] - Format options
* @returns {object} Formatted attributes for database
*/
format(attributes: object, options?: object): object;Methods for building database queries on model instances.
/**
* Access or modify underlying query builder
* @param {Function} [callback] - Function to modify query builder
* @returns {Model} Model instance for chaining
*/
query(callback?: (queryBuilder: Knex.QueryBuilder) => void): Model;
/**
* Add where clause to query
* @param {...*} args - Where clause arguments
* @returns {Model} Model instance for chaining
*/
where(...args: any[]): Model;
/**
* Add order by clause
* @param {string} column - Column to order by
* @param {string} [direction='asc'] - Sort direction
* @returns {Model} Model instance for chaining
*/
orderBy(column: string, direction?: 'asc' | 'desc'): Model;Additional utility methods for model manipulation.
/**
* Create shallow copy of model
* @returns {Model} Cloned model instance
*/
clone(): Model;
/**
* Re-fetch model from database, updating current instance
* @param {object} [options] - Refresh options
* @returns {Promise<Model>} Refreshed model
*/
refresh(options?: object): Promise<Model>;
/**
* Count related records
* @param {string} [column='*'] - Column to count
* @param {object} [options] - Count options
* @returns {Promise<number>} Count of related records
*/
count(column?: string, options?: object): Promise<number>;
/**
* Get related model or collection by name
* @param {string} relationName - Name of the relation
* @returns {Model|Collection} Related model or collection
*/
related(relationName: string): Model | Collection;
/**
* Set automatic timestamp attributes
* @param {object} [options] - Timestamp options
* @returns {object} Timestamp attributes object
*/
timestamp(options?: object): object;const User = bookshelf.model('User', {
// Required: table name
tableName: 'users',
// Optional: custom primary key
idAttribute: 'user_id',
// Optional: enable timestamps
hasTimestamps: true,
// Optional: default values
defaults: {
active: true,
role: 'user'
},
// Optional: serialization control
hidden: ['password', 'token'],
visible: ['id', 'name', 'email', 'created_at'],
// Custom instance methods
posts() {
return this.hasMany('Post');
},
profile() {
return this.hasOne('Profile');
},
// Custom validation
initialize() {
this.on('saving', this.validateSave);
},
validateSave(model, attrs, options) {
if (!attrs.email) {
throw new Error('Email is required');
}
}
}, {
// Static methods
findByEmail(email) {
return this.where('email', email).fetch();
},
active() {
return this.where('active', true);
}
});