pub trait ModelEvents: Model {
// Provided methods
fn before_insert(&mut self) -> Result<()> { ... }
fn after_insert(&mut self) -> Result<()> { ... }
fn before_update(&mut self) -> Result<()> { ... }
fn after_update(&mut self) -> Result<()> { ... }
fn before_delete(&mut self) -> Result<()> { ... }
fn after_delete(&mut self) -> Result<()> { ... }
fn on_load(&mut self) -> Result<()> { ... }
fn on_refresh(&mut self) -> Result<()> { ... }
fn on_attribute_change(&mut self, changes: &[AttributeChange]) -> Result<()> { ... }
}Expand description
Lifecycle event hooks for model instances.
Models can implement this trait to receive callbacks at various points in the persistence lifecycle: before/after insert, update, and delete.
All methods have default no-op implementations, so you only need to override the ones you care about.
§Example
use sqlmodel_core::{Model, ModelEvents, Result};
#[derive(Model)]
struct User {
id: Option<i64>,
name: String,
created_at: Option<i64>,
updated_at: Option<i64>,
}
impl ModelEvents for User {
fn before_insert(&mut self) -> Result<()> {
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
self.created_at = Some(now);
self.updated_at = Some(now);
Ok(())
}
fn before_update(&mut self) -> Result<()> {
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
self.updated_at = Some(now);
Ok(())
}
}Provided Methods§
Sourcefn before_insert(&mut self) -> Result<()>
fn before_insert(&mut self) -> Result<()>
Called before a new instance is inserted into the database.
Use this to set default values, validate data, or perform any pre-insert logic. Return an error to abort the insert.
Sourcefn after_insert(&mut self) -> Result<()>
fn after_insert(&mut self) -> Result<()>
Called after an instance has been successfully inserted.
The instance now has its auto-generated ID (if applicable). Use this for post-insert notifications or logging.
Sourcefn before_update(&mut self) -> Result<()>
fn before_update(&mut self) -> Result<()>
Called before an existing instance is updated in the database.
Use this to update timestamps, validate changes, or perform any pre-update logic. Return an error to abort the update.
Sourcefn after_update(&mut self) -> Result<()>
fn after_update(&mut self) -> Result<()>
Called after an instance has been successfully updated.
Use this for post-update notifications or logging.
Sourcefn before_delete(&mut self) -> Result<()>
fn before_delete(&mut self) -> Result<()>
Called before an instance is deleted from the database.
Use this for cleanup, validation, or any pre-delete logic. Return an error to abort the delete.
Sourcefn after_delete(&mut self) -> Result<()>
fn after_delete(&mut self) -> Result<()>
Called after an instance has been successfully deleted.
Use this for post-delete notifications or logging.
Sourcefn on_load(&mut self) -> Result<()>
fn on_load(&mut self) -> Result<()>
Called after an instance has been loaded from the database.
Use this to perform post-load initialization or validation.
Sourcefn on_refresh(&mut self) -> Result<()>
fn on_refresh(&mut self) -> Result<()>
Called after an instance has been refreshed from the database.
Use this to handle any logic needed after a refresh operation.
Sourcefn on_attribute_change(&mut self, changes: &[AttributeChange]) -> Result<()>
fn on_attribute_change(&mut self, changes: &[AttributeChange]) -> Result<()>
Called when individual attributes are detected as changed.
This is invoked during flush when the change tracker detects that specific fields have been modified. Each change includes the field name and the old/new values as JSON.
Return an error to abort the flush.
§Example
impl ModelEvents for User {
fn on_attribute_change(&mut self, changes: &[AttributeChange]) -> Result<()> {
for change in changes {
if change.field_name == "email" {
// trigger verification
}
}
Ok(())
}
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.