Skip to main content

Models

Models are the heart of Ryx. In Rust, a model is a struct annotated with #[model].

Basic Modelโ€‹

use ryx_rs::model;

#[model]
#[table("posts")]
struct Post {
#[field(pk)]
id: i64,
title: String,
slug: String,
views: i64,
active: bool,
body: Option<String>,
}

Field Attributesโ€‹

AttributeDescription
#[field(pk)]Primary key
#[field(unique)]Unique constraint
#[field(nullable)]Allows NULL
#[field(index)]Create an index
#[field(column = "col_name")]Override the column name
#[field(db_type = "TEXT")]Force a specific SQL type
#[field(default = "0")]Default value expression

Table Namingโ€‹

Without #[table(...)], Ryx converts the struct name to snake_case plural:

StructTable
Postposts
BlogPostblog_posts
Categorycategories

Override with #[table("custom_name")].

Supported Field Typesโ€‹

Rust TypeSQL Column
i64BIGINT
StringTEXT / VARCHAR
boolBOOLEAN
f64DOUBLE PRECISION
chrono::NaiveDateTimeTIMESTAMP
chrono::NaiveDateDATE
Option<T>Nullable version of T
Vec<T>(multi-value bind, e.g. IN clauses)

All types implement the IntoSqlValue trait for automatic query parameter conversion.

Relationshipsโ€‹

Use #[relation(...)] for foreign keys:

#[model]
struct Author {
#[field(pk)]
id: i64,
name: String,
}

#[model]
#[relation(model = "Author", fk_column = "author_id", name = "author")]
struct Post {
#[field(pk)]
id: i64,
title: String,
author_id: i64,
author: Option<Author>,
}
ParameterDescription
modelThe related model type
fk_columnThe foreign key column name
nameThe struct field name (must match)
to_table(optional) Target table, defaults to related model's table
to_field(optional) Target column, defaults to primary key

How #[model] Worksโ€‹

The #[model] attribute is shorthand for combining:

#[derive(Serialize, Deserialize)]  // from serde
#[derive(Model)] // Model + Relationships traits
#[derive(FromRow)] // Row deserialization
// All in one step

Next Stepsโ€‹