Models
A model maps one table to a Rust type, and names the columns that insert and update may write. The OrbitModel derive writes the row mapping and the model from attributes:
use orbit_orm::{Model, OrbitModel};
#[derive(OrbitModel)]
#[orbit(table = "posts")]
struct Post {
id: i64,
#[orbit(fillable)]
title: String,
#[orbit(column = "view_count", fillable)]
views: Option<i64>,
}
The derive works on a struct with named fields. It does not support generic structs, tuple structs or enums. The field types must be types that sqlx can read from MySQL, such as i64, String, bool and Option of those.
Import Model as well, as the example does. It provides Post::query(), and the derive does not add it to the scope.
Attributes
Attributes go in #[orbit(...)]. A struct takes these keys:
table = "..."sets the table name. The name must not be empty. See Table names.primary_key = "..."sets the primary key column. The default isid. It must be the column of a field that is not skipped, or the derive fails to compile.
A field takes these keys:
column = "..."sets the column name, when it differs from the field name.fillableadds the column to the list thatinsertandupdatemay write. By default no column is fillable.skipleaves the field out of the row. The field is set to itsDefaultvalue when a row is read. A skipped field cannot havecolumnorfillable.
An unknown key is a compile error.
Table names
Without table, the table name is the struct name in snake case, with its last word made plural, as in Laravel's Eloquent:
Flightusesflights.UserProfileusesuser_profiles. Only the last word,Profile, is pluralized.Categoryusescategories.Personusespeople.
The plural follows the English rules that Laravel's Pluralizer uses, including its irregular and uncountable words. These rules cover ASCII letters only. A word that matches no rule gets a plain s. When the name differs from the table, set table: an explicit name is used as written.
The primary key
The primary key is id unless primary_key says otherwise. find and find_or_fail search by it, and first does not use it for ordering. A table with a text key:
#[derive(OrbitModel)]
#[orbit(table = "tags", primary_key = "slug")]
struct Tag {
#[orbit(fillable)]
slug: String,
#[orbit(fillable)]
label: String,
}
A hand-written model
Without the derive, write the two impls yourself. Rows are read with sqlx's FromRow, and Model gives the table, the primary key and the fillable columns. This is the same model as the first example:
use orbit_orm::Model;
use sqlx::mysql::MySqlRow;
use sqlx::{FromRow, Row};
struct Post {
id: i64,
title: String,
views: i64,
}
impl<'r> FromRow<'r, MySqlRow> for Post {
fn from_row(row: &'r MySqlRow) -> Result<Self, sqlx::Error> {
Ok(Self {
id: row.try_get("id")?,
title: row.try_get("title")?,
views: row.try_get("views")?,
})
}
}
impl Model for Post {
const TABLE: &'static str = "posts";
const FILLABLE: &'static [&'static str] = &["title", "views"];
}
The Model trait has three constants and one method:
TABLE, the table name. It has no default, so it must be set.PRIMARY_KEY, the primary key column. The default is"id".FILLABLE, the columns thatinsertandupdatemay write. The default is an empty list.query(), which starts a query on the table. It is provided, so it needs no code.
The hand-written model needs sqlx in the app. See Installation.
Next, see Queries for the methods a model's query() returns.
Orbit