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

Ordering & Pagination

Ordering

Use .order_by() to sort results. Each model generates a ModelOrderByInput enum with a variant for every field.

#![allow(unused)]
fn main() {
use generated::user::order::UserOrderByInput;
use ferriorm_runtime::prelude::SortOrder;

let users = client
    .user()
    .find_many(UserWhereInput::default())
    .order_by(UserOrderByInput::CreatedAt(SortOrder::Desc))
    .exec()
    .await?;
}

SortOrder

VariantSQL
SortOrder::AscASC
SortOrder::DescDESC

Multiple Order Clauses

Chain multiple .order_by() calls. They are applied in order (first call is the primary sort):

#![allow(unused)]
fn main() {
let users = client
    .user()
    .find_many(UserWhereInput::default())
    .order_by(UserOrderByInput::Role(SortOrder::Asc))
    .order_by(UserOrderByInput::Email(SortOrder::Asc))
    .exec()
    .await?;
// SQL: ORDER BY "role" ASC, "email" ASC
}

Available Fields

Every column in the model has a corresponding variant:

#![allow(unused)]
fn main() {
pub enum UserOrderByInput {
    Id(SortOrder),
    Email(SortOrder),
    Name(SortOrder),
    Role(SortOrder),
    CreatedAt(SortOrder),
    UpdatedAt(SortOrder),
}
}

Pagination

Use .skip(n) and .take(n) for offset-based pagination. Both accept i64 values.

MethodSQLDescription
.take(n)LIMIT nMaximum number of records to return
.skip(n)OFFSET nNumber of records to skip

Basic Pagination

#![allow(unused)]
fn main() {
// Page 1: first 10 records
let page1 = client
    .user()
    .find_many(UserWhereInput::default())
    .order_by(UserOrderByInput::CreatedAt(SortOrder::Desc))
    .take(10)
    .exec()
    .await?;

// Page 2: next 10 records
let page2 = client
    .user()
    .find_many(UserWhereInput::default())
    .order_by(UserOrderByInput::CreatedAt(SortOrder::Desc))
    .skip(10)
    .take(10)
    .exec()
    .await?;
}

Paginated List Helper

A common pattern for API endpoints:

#![allow(unused)]
fn main() {
async fn list_users(
    client: &FerriormClient,
    page: i64,
    page_size: i64,
) -> Result<(Vec<User>, i64), FerriormError> {
    let filter = UserWhereInput::default();

    let total = client
        .user()
        .count(filter.clone())
        .exec()
        .await?;

    let users = client
        .user()
        .find_many(filter)
        .order_by(UserOrderByInput::CreatedAt(SortOrder::Desc))
        .skip((page - 1) * page_size)
        .take(page_size)
        .exec()
        .await?;

    Ok((users, total))
}
}

Ordering with Select

Ordering works with .select() queries too:

#![allow(unused)]
fn main() {
let partials = client
    .user()
    .find_many(UserWhereInput::default())
    .select(UserSelect { id: true, email: true, ..Default::default() })
    .order_by(UserOrderByInput::Email(SortOrder::Asc))
    .skip(0)
    .take(50)
    .exec()
    .await?;
}

Note: Always include an order_by clause when paginating. Without it, the database does not guarantee a stable ordering, and pages may contain duplicate or missing records.