Expand description
Chain relation methods on a Many handle to traverse multi-step
associations without declaring a via relation on the schema.
user.todos().category() produces an Association whose path is two
steps long (User → todos → category). The query engine lowers this by
unfolding into nested IN-subqueries against the outermost relation.
Functions§
- chain_
dedupes_ when_ todos_ share_ category - Many todos sharing a single category yield exactly one category row in the chain result — IN dedupes against the outermost relation.
- chain_
from_ empty_ source_ is_ empty - Empty source: a user with no todos produces an empty chain result.
- chain_
scopes_ per_ starting_ user - The chain respects the starting source: each user’s chain returns only the categories their own todos belong to, even when the data sets overlap.
- chain_
skips_ null_ belongs_ to Deferred<Option<_>>in the chain skipsNULLforeign keys. Todos with no category contribute nothing to the chain.- chain_
then_ filter Many::filter(expr)after a chain applies a filter to the final relation. The result is the chain’s category set narrowed by the filter.- four_
step_ chain - A 4-step chain (
Org → Team → Project → Issue → Tag) drives thepeel_first_steploop through three iterations before reducing to a single-step rewrite. Guards against regressions in the depth-independent part of the unfolder. - has_
many_ through_ has_ many - Two HasMany hops in succession (
Author → posts → comments). The lowering unfolds into nested IN-subqueries on eachBelongsTopair. - three_
step_ chain - A 3-step chain (
User → Project → Task → Tag) walks the planner’s unfolder more than once. Verifies the recursive nesting and the chain ofBelongsTorewrites at each hop. - user_
todos_ category - Happy path: HasMany → BelongsTo chain returns the distinct set of categories the user’s todos belong to, with no duplicates even when the user has multiple todos in the same category.