Peter Amiri
06/22/2026, 3:15 PMenum(property="status", values="draft,published,archived") registers a validation, three boolean checkers (isDraft, isPublished, isArchived), and three scopes (.draft(), .published(), .archived()). All parameterised.
• The chainable query builder — .where("col", value), .whereIn, .whereBetween, .orderBy, .limit, .get(). Auto-quoting + type validation on the way to SQL, so integer/float/boolean payloads can't sneak past the binding layer.
• Three features, one design — they all return deferred-query proxies that materialise into the same finder-argument struct on a terminal call. The chain reads top-to-bottom in the order you'd describe the query out loud.
Side effect of writing the post: framework fix (#2736) — whereIn / whereNotIn with empty arrays no longer emit malformed IN () SQL. whereIn(empty) now sets a flag the terminals honour (count → 0, exists → false, findAll → empty query, etc.); whereNotIn(empty) is a no-op (exclude-none = match-all). Same user-facing behaviour as Rails / Sequel / Django / Eloquent. Fourteen regression specs locked in.