#[derive(ModelColumns)]
{
// Attributes available to this derive:
#[columns]
}
Expand description
Derive a model’s ModelColumns: the table a resource lists it
in and the detail page it shows it on, when the resource declares neither.
#[derive(Debug, Clone, toasty::Model, tablo_core::ModelColumns)]
pub struct User {
#[key]
#[auto]
pub id: uuid::Uuid,
pub name: String,
pub role: Role,
pub active: bool,
#[columns(skip)]
pub password_hash: String,
#[default(jiff::Timestamp::now())]
pub created_at: jiff::Timestamp,
}
// Lists `name`, `role`, `active` and `created_at`, and shows them on the detail page.
let table = <User as tablo_core::ModelColumns>::table();Each field shows whoever writes it, the person through a form or Toasty through a
#[default] or an #[update], in a column its type picks:
- a
bool: a sortableBooleanColumn, yes or no; - a
StringorOption<String>: a sortable, searchableTextColumn; - any other
FormScalar: a sortableTextColumn, anOptionsenum by its label; - an
EmbeddedFormvalue: anEmbeddedColumn, leaf by leaf, on the detail page only; - a list of
FormInputitems: aRepeaterColumn, on the detail page only; - a
Vecof aFormScalar, such as a multiple choice’s: aListColumn, a badge per value; - any other type: no column.
No column shows a key Toasty generates, a #[version] field, a relation or its foreign
key, which only a declared RelationColumn shows, by the related
record’s title, or a TenantId or Option<TenantId> field, which belongs to the
resource’s Tenancy. An #[auto] created_at or updated_at shows
like any timestamp. A #[version] field is what
ModelColumns::version returns, so the edit form refuses a
save another save overtook.
Every other field shows, a secret such as a password hash or an API token included, to
anyone the policy lets view the list: mark it #[columns(skip)], which leaves it out of
the table, its search and export, and the detail page.
§Per-field attributes
The other #[columns(..)] keys shape the column the field’s type picks, in the table and
on the detail page, through the column’s own builder:
#[columns(label = "Amount due")]— the column’s label, and its filter’s (TextColumn::label);#[columns(badge)]— a text column’s value as a badge (TextColumn::badge);#[columns(money = EUR)]— a number as an amount of aCurrency: a bare three-letter uppercase code names one of its constants, and any other expression is the currency itself, such asmoney = SHOP_CURRENCYfor the app’s own constant ormoney = Currency::new("CHF")(TextColumn::money);#[columns(hidden_by_default)]— a table column each reader may show, hidden at first (TextColumn::hidden_by_default);#[columns(filter)]— a filter on the table: aTernaryFilterfor abool, aDateFilterover a range of days for a date or a timestamp, optional or not, aSelectFilterfor anOptionsenum. AnOption<bool>or an optional enum takes no built-in filter, sofilteron one fails to compile: declare its filter on the resource’s table.
#[derive(Debug, Clone, toasty::Model, tablo_core::ModelColumns)]
pub struct Invoice {
#[key]
#[auto]
pub id: uuid::Uuid,
#[columns(badge, filter)]
pub status: Status,
#[columns(label = "Amount due", money = EUR)]
pub total_cents: i64,
#[columns(hidden_by_default, filter)]
pub issued_at: jiff::Timestamp,
}A key the field’s column does not fit fails to compile at the key, such as badge on a
bool or money on a String, as does filter on a type no built-in filter matches,
label on a field no column shows, and hidden_by_default on one the table leaves out. So
do an unknown or repeated key, skip beside another key, any key on a field the derive
already leaves out, and a generic model.
The derive reads the model, not a form: a file path shows as text and a String an
#[form(options = ..)] key labels shows its stored value. Declare a
FileColumn or a formatted TextColumn for
them.
A resource replaces either default with ResourceDef::table
or ResourceDef::detail, and extends one by starting from
it: User::table().filters(..), with ModelColumns in scope,
which adds its filters after the derived ones; mounting refuses two filters on one field. A
declared table is also the detail page’s default: a resource that declares a table and no
detail page shows the table’s columns there.
Derive a model’s default table and detail page; documented on the tablo-core re-export.