Skip to content
Concepts

CRUD and queries

Maya creates an account in a writing app. Later she can update her display name or remove the account. Rent generates methods for those everyday tasks from your RSL models.

Create a user

Build the values you want to save, then call save() to write them to the database:

let maya = client
    .create_user()
    .name("Maya")
    .email("maya@example.com")
    .save()
    .await?;

Find the people to display

Filter and order the matching rows, then choose how many to load:

let adults = client
    .user()
    .age_ge(18)
    .order_by_desc(user::User::created_at)
    .limit(25)
    .all()
    .await?;

Update a name

Select the user you intend to change and supply the new value:

let changed = client
    .update_user()
    .id_eq(maya.id)
    .name("Maya Chen")
    .save()
    .await?;

Delete a user

Use the same filter style to identify the rows to remove:

let removed = client
    .delete_user()
    .id_eq(maya.id)
    .exec()
    .await?;

Follow a relationship

Filter through relationships without writing a subquery:

let authors = client
    .user()
    .where_posts(|posts| posts.published_eq(true))
    .all()
    .await?;

Return a small page

For large or narrow reads, use keyset cursors, bounded streams, and typed tuple projections:

let identities = client
    .user()
    .after_id(last_id)
    .limit(100)
    .select((user::User::id, user::User::name))
    .all()
    .await?;

When the database is called

The setter chain does not send one query per setter. Rent emits one mutation at save(). PostgreSQL and SQLite return the complete entity from that same INSERT ... RETURNING request. MySQL uses the insert identifier and one follow-up read because it lacks equivalent general-purpose returning support.

Generated predicate families include equality, inequality, greater/greater-or-equal, less/less-or-equal, membership (_in and _not_in), and null/not-null, plus _contains, _starts_with, _ends_with, and _contains_insensitive on string fields, depending on the field's type and nullability. Thus normal code is client.document().id_eq(id).version_eq(version). The column token form, Document::id.eq(id), remains for expressions that must be stored, reused, or combined dynamically with &, |, !, JSON operations, or extension operators.

Builder calls collect values without contacting the database. Methods such as save(), all(), only(), count(), and exec() run the operation.