Skip to main content

Runtime Querying

The read side of the runtime is Laravel-like and should stay predictable.

Primary query shapes

When to use each read path

User.find(id)

Use this when:
  • you already have the primary key
  • the service needs one record or null
  • the next step is update, patch, delete, or restore

User.findOneBy(field, value)

Use this when:
  • the lookup key is not the primary key
  • the service expects one record or null
  • the code should read like “find the user by email”

where(...).orderBy(...).limit(...).get()

Use this when:
  • you are building list endpoints
  • ordering matters
  • limits should be explicit

new User().all()

Use this when:
  • you want the plain instance collection-read path
  • you are intentionally reading the full collection
  • you are not expressing filter semantics

Safe-finder chain

Rules:
  • where(field, value) filters by declared schema fields
  • orderBy(field, direction) supports asc and desc
  • always pass the direction explicitly
  • limit(count) should be explicit on user-facing list endpoints

Eager loading

Use eager loading only when the model defines explicit relation methods.
Important rules:
  • schema relation metadata alone is not enough
  • with(...) and load(...) require explicit relation methods
  • eager loading belongs in services, not controllers

Scopes

Use scopes when:
  • a query pattern repeats
  • you want a named query contract
  • you want controllers to stay thin