Skip to main content

Instance Methods

Hysteria ORM models provide instance methods that allow you to work with individual model instances. These methods operate on the model instance itself and require the model to have a primary key defined.

Overview

Instance methods are called on model instances rather than the model class. They provide a convenient way to perform operations on a specific record.

Important: All instance methods require the model to have a primary key defined. If the model doesn't have a primary key, these methods will throw a HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY.

Methods

save()

Saves the model instance to the database. If the primary key is not set, it performs an insert. If the primary key is set, it performs an update.

// Insert a new record
const user = new User();
user.name = "John Doe";
user.email = "john@example.com";
user.age = 30;
await user.save();

// Update an existing record
const existingUser = await User.findOne({ where: { id: 1 } });
if (existingUser) {
existingUser.name = "Jane Doe";
await existingUser.save();
}

Options:

  • trx: Transaction instance for running the operation within a transaction
const trx = await sql.transaction();
try {
const user = new User();
user.name = "John Doe";
await user.save({ trx });
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;
}

Throws:

  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY if the model has no primary key defined

update(payload, options?)

Updates the model instance in the database with the provided payload. The model must have a primary key value set.

const user = new User();
user.id = 1;
user.name = "John Doe";
user.email = "john@example.com";

// Update specific fields
await user.update({
name: "Jane Doe",
age: 35,
});

Parameters:

  • payload: Partial object containing the fields to update
  • options: Optional object with trx for transaction support
const trx = await sql.transaction();
try {
await user.update({ name: "Updated Name" }, { trx });
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;
}

Throws:

  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY if the model has no primary key defined
  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY_VALUE if the primary key value is not set

softDelete(options?, methodOptions?)

Soft deletes the model instance by setting the soft delete column to a value (default: current UTC datetime). The record remains in the database but is filtered out by default queries.

const user = await User.findOne({ where: { id: 1 } });
if (user) {
await user.softDelete();
}

Parameters:

  • options: Optional object with:
    • column: Custom column name for soft delete (default: deletedAt)
    • value: Custom value to set (default: current UTC datetime)
  • methodOptions: Optional object with trx for transaction support
// Custom soft delete column and value
const customDate = new Date("2024-01-01");
await user.softDelete({
column: "deletedAt",
value: customDate,
});

// With transaction
const trx = await sql.transaction();
try {
await user.softDelete(undefined, { trx });
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;
}

Throws:

  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY if the model has no primary key defined
  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY_VALUE if the primary key value is not set

Note: Soft deleted records are automatically filtered out by find, findOne, and other query methods unless you use ignoreHooks: ["beforeFetch"] in your query options.

delete(options?)

Permanently deletes the model instance from the database.

const user = await User.findOne({ where: { id: 1 } });
if (user) {
await user.delete();
}

Options:

  • trx: Transaction instance for running the operation within a transaction
const trx = await sql.transaction();
try {
await user.delete({ trx });
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;
}

Throws:

  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY if the model has no primary key defined
  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY_VALUE if the primary key value is not set

refresh(options?)

Refreshes the model instance from the database, updating all fields with the current values.

const user = await User.findOneByPrimaryKey(1);

// Update the record directly in the database
await User.updateRecord(user, { name: "Updated Name", age: 40 });

// Refresh the instance to get the latest data
await user.refresh();

console.log(user.name); // "Updated Name"
console.log(user.age); // 40

Options:

  • trx: Transaction instance for running the operation within a transaction
const trx = await sql.transaction();
try {
await User.updateRecord(user, { name: "Transaction Updated" }, { trx });
await user.refresh({ trx });
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;
}

Throws:

  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY if the model has no primary key defined
  • HysteriaError with code MODEL_HAS_NO_PRIMARY_KEY_VALUE if the primary key value is not set

mergeProps(data)

Merges the provided data with the model instance, updating only the specified properties.

const user = new User();
user.name = "John Doe";
user.email = "john@example.com";
user.age = 25;

// Merge new values
user.mergeProps({
name: "Jane Doe",
age: 30,
});

console.log(user.name); // "Jane Doe"
console.log(user.age); // 30
console.log(user.email); // "john@example.com" (unchanged)

Parameters:

  • data: Partial object containing the fields to merge

Chaining Instance Methods

Instance methods can be chained together for convenient workflows:

// Create, update, refresh, and soft delete
const user = new User();
user.name = "Chain Test";
user.email = "chain@example.com";
user.age = 25;

await user.save(); // Insert
await user.update({ name: "Chain Updated" }); // Update
await User.updateRecord(user, { age: 50 }); // Update via static method
await user.refresh(); // Refresh to get latest data
await user.softDelete(); // Soft delete

Best Practices

MethodWhen to Use
save()Both inserts (no PK) and updates (has PK)
update()Update specific fields only
refresh()After external updates to sync instance
softDelete()Preserve data for audit purposes
delete()Permanently remove records
mergeProps()Update instance properties without saving
tip

Always check for null values when using findOne() before calling instance methods.


Next: Model Views