rent
Learn by example

19. Production schema options

The first chapter kept the schema small. This chapter revisits the same User and Post model with the controls needed by mature applications.

Use aligned field lists for a tenant-scoped compound foreign key:

author User @relation(fields: [tenant_id, author_id], references: [tenant_id, id], map: "posts_author_fkey", onDelete: Restrict, onUpdate: Cascade)

Choose physical names and default ordering for a many-to-many relationship:

tags Tag[] @relation("PostTags") @rent.join(table: "post_tags", columns: [post_id, tag_id], constraints: [post_tags_post_fkey, post_tags_tag_fkey]) @rent.order(field: "name")

rent migrate diff, plan, and apply create that join table, its composite primary key, and both foreign keys from the same declaration used to generate the relationship client.

Database expressions can own defaults:

public_id Uuid @rent.defaultSql("gen_random_uuid()")

Advanced indexes remain part of the RSL schema too:

@@unique([tenant_id, slug(sort: Desc)], map: "posts_published_slug", where: "deleted_at IS NULL", include: [title], type: BTree)
@@index([], map: "posts_lower_title", expression: "lower(title)")

RSL semantic validation reports invalid combinations before generation or migration, including missing referenced fields and misaligned compound foreign keys.

The complete advanced schema is crates/rent/examples/tutorial_18_schema_options/schema.rsl. Run cargo run -p rent --example tutorial_18_schema_options. The same schema validation runs under nextest.