Relationship Types
Out of the box, Rune supports three categories of relationships, represented by property wrappers@BelongsTo, @HasMany, and @HasOne.
Consider a database with tables users, todos, tags, todo_tags.
BelongsTo
ABelongsTo is the simplest kind of relationship. It represents the child of a 1-1 or 1-M relationship. The child typically has a column referencing the primary key of another table.
@BelongsTo property wrapper and types, Rune will infer a user_id key on Todo and an id key on users when eager loading. If the keys differ, for example users local key is my_id you may access the RelationshipMapping in Model.mapRelations and override either key with to(...) or from(...). to overrides the key on the destination of the relation, from overrides the key on the model the relation is on.
HasMany
A “HasMany” relationship represents the Parent side of a 1-M or a M-M relationship.id on users and a foreign key user_id on todos. You can override either using the same mapRelations function.
HasOne
Has one, a has relationship where there is only one value, functions the same asHasMany except it wraps single value, not an array. Overriding keys works the same way.
HasMany through
The.through(...) mapping provides a convenient way to access distant relations via an intermediate relation.
Consider tables representing a CI system user, projects, workflows.
through(...) function.
.from & .to functions and you can override the intermediary table keys with the from and to parameters of through.
HasOne through
The.through(...) mapping can also be applied to a HasOne relationship. It functions the same, with overrides available for from, throughFrom, throughTo, and to.
ManyToMany
Often you’ll have relationships that are defined by a pivot table containing references to each side of the relationship. You can use thethroughPivot function to define a @HasMany relationship to function this way.
through, keys are inferred but you may specify from and to parameters to indicate the keys on the pivot table.
Eager Loading Relationships
In order to access a relationship property of a queriedModel, you need to load that relationship first. You can “eager load” it using the .with() function on a ModelQuery. Eager loading refers to preemptively, or “eagerly”, loading a relationship before it is used. Eager loading also solves the N+1 problem; if N Pets are returned with a query, you won’t need to run N queries to find each of their Owners. Instead, a single, followup query will be run that finds all Owners for all Pets fetched.
This function takes a KeyPath to a relationship and runs a query to fetch it when the initial query is finished.
Model using .with().
.with() function takes a KeyPath to a relationship not a Model, so be sure to preface your key path with a $.
Warning 2: If you access a relationship before it’s loaded, the program will fatalError. Be sure a relationship is loaded with eager loading before accessing it!
Nested Eager Loading
You may want to load relationships on your eager loaded relationshipModels. You can do this with the second, closure argument of with().
Consider three relationships, Homework, Student, School. A Homework belongs to a Student and a Student belongs to a School.
You might represent them in a database like so
Homework, you can use nested eager loading like so

