_SQLAssociation

An SQL association is a non-empty chain of steps which starts at the “pivot” and ends on the “destination”:

SQLAssociation.swift:52
struct _SQLAssociation
// SELECT origin.*, destination.*
// FROM origin
// JOIN pivot ON ...
// JOIN ...
// JOIN ...
// JOIN destination ON ...
Origin.including(required: association)

For direct associations such as BelongTo or HasMany, the chain contains a single element, the “destination”, without intermediate step:

// "Origin" belongsTo "destination":
// SELECT origin.*, destination.*
// FROM origin
// JOIN destination ON destination.originId = origin.id
let association = Origin.belongsTo(Destination.self)
Origin.including(required: association)

Indirect associations such as HasManyThrough have one or several intermediate steps:

// "Origin" has many "destination" through "pivot":
// SELECT origin.*, destination.*
// FROM origin
// JOIN pivot ON pivot.originId = origin.id
// JOIN destination ON destination.id = pivot.destinationId
let association = Origin.hasMany(
    Destination.self,
    through: Origin.hasMany(Pivot.self),
    via: Pivot.belongsTo(Destination.self))
Origin.including(required: association)

// "Origin" has many "destination" through "pivot1" and  "pivot2":
// SELECT origin.*, destination.*
// FROM origin
// JOIN pivot1 ON pivot1.originId = origin.id
// JOIN pivot2 ON pivot2.pivot1Id = pivot1.id
// JOIN destination ON destination.id = pivot.destinationId
let association = Origin.hasMany(
    Destination.self,
    through: Origin.hasMany(Pivot1.self),
    via: Pivot1.hasMany(
        Destination.self,
        through: Pivot1.hasMany(Pivot2.self),
        via: Pivot2.belongsTo(Destination.self)))
Origin.including(required: association)