Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Field Attributes Reference

Complete reference for #[crudcrate(...)] attributes on fields.

Syntax

#[crudcrate(attribute1, attribute2 = value, ...)]
pub field_name: FieldType,

Core Attributes

primary_key

Marks the field as the primary key.

#[crudcrate(primary_key)]
pub id: i32,

Required: Yes (exactly one field) Type: Flag


exclude(...)

Exclude field from specific generated models.

#[crudcrate(exclude(create, update))]
pub id: Uuid,

#[crudcrate(exclude(one, list))]
pub password_hash: String,

Type: List of targets Targets:

  • one - Response model (GET /items/:id)
  • create - Create model (POST /items)
  • update - Update model (PUT /items/:id)
  • list - List model (GET /items)
  • all - Shorthand for one, list. Does not touch create or update. Unrelated to join(all), where all means the list endpoint.
  • scoped - Scoped response models (when ScopeCondition is active). Also strips the field from filterable/sortable lists in scoped context. See Public & Private Endpoints.

filterable

Enable filtering on this field.

#[crudcrate(filterable)]
pub status: String,

Type: Flag Effect: Allows ?filter={"status":"value"} and ?status_eq=value


sortable

Enable sorting on this field.

#[crudcrate(sortable)]
pub created_at: DateTimeUtc,

Type: Flag Effect: Allows ?sort=["created_at","DESC"]


fulltext

Include field in fulltext search.

#[crudcrate(fulltext)]
pub title: String,

#[crudcrate(fulltext)]
pub content: String,

Type: Flag Effect: Field included when using ?q=search+terms


Default Value Attributes

on_create

Set default value when creating new records.

#[crudcrate(on_create = Uuid::new_v4())]
pub id: Uuid,

#[crudcrate(on_create = chrono::Utc::now())]
pub created_at: DateTimeUtc,

#[crudcrate(on_create = "pending".to_string())]
pub status: String,

#[crudcrate(on_create = 0)]
pub view_count: i32,

Type: Rust expression When: Evaluated during create operation


on_update

Set default value when updating records.

#[crudcrate(on_update = chrono::Utc::now())]
pub updated_at: DateTimeUtc,

Type: Rust expression When: Evaluated during every update operation


Relationship Attributes

non_db_attr

Marks field as non-database (for computed or relationship fields).

#[sea_orm(ignore)]
#[crudcrate(non_db_attr)]
pub comments: Vec<Comment>,

Type: Flag Required: Yes, when using join(...)


join(...)

Configure relationship loading.

// Load in get_one only
#[crudcrate(non_db_attr, join(one))]
pub comments: Vec<Comment>,

// Load in both get_one and get_all
#[crudcrate(non_db_attr, join(one, all))]
pub author: Option<User>,

// Limit recursion depth
#[crudcrate(non_db_attr, join(one, all, depth = 2))]
pub nested: Vec<Nested>,

// Two foreign keys to the same parent: pick the relation variant
#[crudcrate(non_db_attr, join(one, all, relation = "Author"))]
pub authored: Vec<Document>,
#[crudcrate(non_db_attr, join(one, all, relation = "Reviewer"))]
pub reviewed: Vec<Document>,

Type: Configuration Parameters:

  • one - Load in single-item responses
  • all - Load in list responses
  • depth = N - Maximum recursion depth (default: 5)
  • relation = "Variant" - Variant of the child’s Relation enum to join through. Needed when the child has more than one foreign key to this entity, since Related can only be implemented once per pair
  • fk_column = "Column" - Child column variant holding the foreign key, bypassing runtime resolution from the RelationDef
  • path = "crate::module" - Module of the child entity when it cannot be derived from the field type

join_filterable(...)

Enable filtering on columns from related entities using dot-notation.

#[sea_orm(ignore)]
#[crudcrate(
    non_db_attr,
    join(one, all),
    join_filterable("make", "year", "color")
)]
pub vehicles: Vec<Vehicle>,

Type: List of column names Effect: Enables ?filter={"vehicles.make":"BMW","vehicles.year_gte":2020} Security: Only listed columns can be filtered - unlisted columns are silently ignored


join_sortable(...)

Enable sorting on columns from related entities using dot-notation.

#[sea_orm(ignore)]
#[crudcrate(
    non_db_attr,
    join(one, all),
    join_sortable("year", "mileage")
)]
pub vehicles: Vec<Vehicle>,

Type: List of column names Effect: Enables ?sort=["vehicles.year","DESC"] Security: Only listed columns can be sorted - unlisted columns fall back to default sort


Common Patterns

Auto-Generated ID

#[sea_orm(primary_key, auto_increment = false)]
#[crudcrate(primary_key, exclude(create, update), on_create = Uuid::new_v4())]
pub id: Uuid,

Managed Timestamps

#[crudcrate(sortable, exclude(create, update), on_create = chrono::Utc::now())]
pub created_at: DateTimeUtc,

#[crudcrate(exclude(create, update), on_create = chrono::Utc::now(), on_update = chrono::Utc::now())]
pub updated_at: DateTimeUtc,

Sensitive Data

#[crudcrate(exclude(one, list))]
pub password_hash: String,

#[crudcrate(exclude(one, list))]
pub api_secret: String,

Searchable Content

#[crudcrate(filterable, sortable, fulltext)]
pub title: String,

#[crudcrate(fulltext, exclude(list))]
pub content: String,

Foreign Key with Relation

#[crudcrate(filterable)]
pub author_id: Uuid,

#[sea_orm(ignore)]
#[crudcrate(non_db_attr, join(one, all, depth = 1))]
pub author: Option<User>,

Relationship with Join Filtering/Sorting

// Enable filtering and sorting on related entity columns
#[sea_orm(ignore)]
#[crudcrate(
    non_db_attr,
    join(one, all, depth = 1),
    join_filterable("make", "year", "color"),
    join_sortable("year", "mileage")
)]
pub vehicles: Vec<Vehicle>,

Enables queries like:

  • ?filter={"vehicles.make":"BMW"}
  • ?sort=["vehicles.year","DESC"]

Computed Field (Read-Only)

#[crudcrate(sortable, exclude(create, update))]
pub view_count: i32,

Complete Example

#[derive(EntityToModels)]
#[crudcrate(generate_router)]
#[sea_orm(table_name = "articles")]
pub struct Model {
    // Primary key with auto-generation
    #[sea_orm(primary_key, auto_increment = false)]
    #[crudcrate(primary_key, exclude(create, update), on_create = Uuid::new_v4())]
    pub id: Uuid,

    // Searchable, filterable, sortable title
    #[crudcrate(filterable, sortable, fulltext)]
    pub title: String,

    // Searchable content, excluded from lists
    #[crudcrate(fulltext, exclude(list))]
    pub content: String,

    // Optional summary for lists
    pub summary: Option<String>,

    // Filterable status
    #[crudcrate(filterable)]
    pub status: ArticleStatus,

    // Foreign key with relationship
    #[crudcrate(filterable)]
    pub author_id: Uuid,

    // Read-only view counter
    #[crudcrate(sortable, exclude(create, update), on_create = 0)]
    pub view_count: i32,

    // Auto-managed timestamps
    #[crudcrate(sortable, exclude(create, update), on_create = chrono::Utc::now())]
    pub created_at: DateTimeUtc,

    #[crudcrate(exclude(create, update), on_create = chrono::Utc::now(), on_update = chrono::Utc::now())]
    pub updated_at: DateTimeUtc,

    // Relationships
    #[sea_orm(ignore)]
    #[crudcrate(non_db_attr, join(one, all, depth = 1))]
    pub author: Option<User>,

    #[sea_orm(ignore)]
    #[crudcrate(non_db_attr, join(one))]
    pub comments: Vec<Comment>,

    // Relationship with join filtering/sorting
    #[sea_orm(ignore)]
    #[crudcrate(
        non_db_attr,
        join(one, all, depth = 1),
        join_filterable("tag_name"),
        join_sortable("tag_name")
    )]
    pub tags: Vec<Tag>,
}

Attribute Compatibility

AttributeCombinable With
primary_keyexclude, on_create
excludeAll except join targets conflict
filterablesortable, fulltext, exclude
sortablefilterable, fulltext, exclude
fulltextfilterable, sortable, exclude
on_createon_update, exclude(create)
on_updateon_create, exclude(update)
non_db_attrjoin, join_filterable, join_sortable (required)
joinnon_db_attr (required), join_filterable, join_sortable
join_filterablenon_db_attr, join, join_sortable
join_sortablenon_db_attr, join, join_filterable

See Also