Skip to content

Entities

Entities are standard SeaORM models with two Oxide conveniences layered on top: the timestamps_behavior!() macro for automatic timestamps and a Model facade for zero-argument queries.

Declare an entity

Convention: src/app/domain/<domain>/models/<name>.rs.

use oxide_db::sea_orm::entity::prelude::*;
use oxide_db::timestamps_behavior;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
#[sea_orm(table_name = "todos")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub title: String,
pub done: bool,
pub created_at: Option<ChronoDateTimeUtc>,
pub updated_at: Option<ChronoDateTimeUtc>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
timestamps_behavior!();

timestamps_behavior!() installs an ActiveModelBehavior::before_save that stamps created_at on insert and updated_at on every write.

Re-export named aliases

In src/app/domain/todo/models/mod.rs:

pub mod todo;
pub use todo::{
ActiveModel as TodoActiveModel,
Column as TodoColumn,
Entity as Todo,
};

Now call sites read Todo::find(), TodoActiveModel { title: Set(...), .. }, TodoColumn::Title.contains(...).

Querying

Use SeaORM’s native API for builders, and the Model facade for the quick common cases.

use oxide_db::sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
use oxide_db::{conn, Model};
use crate::app::domain::todo::models::{Todo, TodoColumn};
// List all
let rows = Todo::get().await?;
// First
let first = Todo::first().await?;
// By id
let one = Todo::find_id(42).await?;
// With a filter — drop to SeaORM native
let done = Todo::find()
.filter(TodoColumn::Done.eq(true))
.all(conn())
.await?;

Todo::find_id is our rename of what would clash with Entity::find() (which returns the SeaORM select builder).

Writing

use oxide_db::sea_orm::{ActiveModelTrait, Set};
use oxide_db::conn;
let new = TodoActiveModel {
title: Set("buy bread".into()),
done: Set(false),
..Default::default()
};
let inserted = new.insert(conn()).await?;
println!("id = {}", inserted.id);

The conn() shortcut

oxide_db::conn() returns the global DatabaseConnection installed by DatabaseServiceProvider. Controllers don’t need to inject Database for simple queries — just use oxide_db::conn and pass it where SeaORM expects &impl ConnectionTrait.

For controllers that want it explicit, declare #[injectable] with db: Arc<Database> and use self.db.conn().