Association

public protocol Association : DerivableRequest, _Association

The base protocol for all associations that define a connection between two record types.

  • The record type at the origin of the association.

    In the belongsTo association below, it is Book:

    struct Book: TableRecord {
        // BelongsToAssociation<Book, Author>
        static let author = belongsTo(Author.self)
    }
    

    Declaration

    Swift

    associatedtype OriginRowDecoder
  • forKey(_:) Default implementation

    Creates an association with the given key.

    This new key impacts how rows fetched from the resulting association should be consumed:

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // Consume rows:
    let request = Player.including(required: Player.team.forKey("custom"))
    for row in Row.fetchAll(db, request) {
        let team: Team = row["custom"]
    }
    

    Default Implementation

    Creates an association with the given key.

    This new key helps Decodable records decode rows fetched from the resulting association:

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    struct PlayerInfo: FetchableRecord, Decodable {
        let player: Player
        let team: Team
    
        static func all() -> QueryInterfaceRequest<PlayerInfo> {
            return Player
                .including(required: Player.team.forKey(CodingKeys.team))
                .asRequest(of: PlayerInfo.self)
        }
    }
    
    let playerInfos = PlayerInfo.all().fetchAll(db)
    print(playerInfos.first?.team)
    

    Declaration

    Swift

    func forKey(_ key: String) -> Self
  • aliased(_:) Extension method

    Creates an association that allows you to define expressions that target a specific database table.

    In the example below, the “team.color = ‘red’” condition in the where clause could be not achieved without table aliases.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.*
    // JOIN team ON ...
    // WHERE team.color = 'red'
    let teamAlias = TableAlias()
    let request = Player
        .including(required: Player.team.aliased(teamAlias))
        .filter(teamAlias[Column("color")] == "red")
    

    When you give a name to a table alias, you can reliably inject sql snippets in your requests:

    // SELECT player.*, custom.*
    // JOIN team custom ON ...
    // WHERE custom.color = 'red'
    let teamAlias = TableAlias(name: "custom")
    let request = Player
        .including(required: Player.team.aliased(teamAlias))
        .filter(sql: "custom.color = ?", arguments: ["red"])
    

    Declaration

    Swift

    public func aliased(_ alias: TableAlias) -> Self
  • select(_:) Extension method

    Creates an association which selects selection.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.color
    // FROM player
    // JOIN team ON team.id = player.teamId
    let association = Player.team.select { db in [Column("color")]
    var request = Player.including(required: association)
    

    Any previous selection is replaced:

    // SELECT player.*, team.color
    // FROM player
    // JOIN team ON team.id = player.teamId
    let association = Player.team
        .select { db in [Column("id")] }
        .select { db in [Column("color") }
    var request = Player.including(required: association)
    

    Declaration

    Swift

    public func select(_ selection: @escaping (Database) throws -> [SQLSelectable]) -> Self
  • annotated(with:) Extension method

    Creates an association which appends selection.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.color, team.name
    // FROM player
    // JOIN team ON team.id = player.teamId
    let association = Player.team
        .select([Column("color")])
        .annotated(with: { db in [Column("name")] })
    var request = Player.including(required: association)
    

    Declaration

    Swift

    public func annotated(with selection: @escaping (Database) throws -> [SQLSelectable]) -> Self
  • filter(_:) Extension method

    Creates an association with the provided predicate promise added to the eventual set of already applied predicates.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.*
    // FROM player
    // JOIN team ON team.id = player.teamId AND 1
    let association = Player.team.filter { db in true }
    var request = Player.including(required: association)
    

    Declaration

    Swift

    public func filter(_ predicate: @escaping (Database) throws -> SQLExpressible) -> Self
  • order(_:) Extension method

    Creates an association with the provided orderings promise.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.*
    // FROM player
    // JOIN team ON team.id = player.teamId
    // ORDER BY team.name
    let association = Player.team.order { _ in [Column("name")] }
    var request = Player.including(required: association)
    

    Any previous ordering is replaced:

    // SELECT player.*, team.*
    // FROM player
    // JOIN team ON team.id = player.teamId
    // ORDER BY team.name
    let association = Player.team
        .order{ _ in [Column("color")] }
        .reversed()
        .order{ _ in [Column("name")] }
    var request = Player.including(required: association)
    

    Declaration

    Swift

    public func order(_ orderings: @escaping (Database) throws -> [SQLOrderingTerm]) -> Self
  • reversed() Extension method

    Creates an association that reverses applied orderings.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.*
    // FROM player
    // JOIN team ON team.id = player.teamId
    // ORDER BY team.name DESC
    let association = Player.team.order(Column("name")).reversed()
    var request = Player.including(required: association)
    

    If no ordering was applied, the returned association is identical.

    // SELECT player.*, team.*
    // FROM player
    // JOIN team ON team.id = player.teamId
    let association = Player.team.reversed()
    var request = Player.including(required: association)
    

    Declaration

    Swift

    public func reversed() -> Self
  • unordered() Extension method

    Creates an association without any ordering.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.*
    // FROM player
    // JOIN team ON team.id = player.teamId
    let association = Player.team.order(Column("name")).unordered()
    var request = Player.including(required: association)
    

    Declaration

    Swift

    public func unordered() -> Self
  • databaseTableName Extension method

    Declaration

    Swift

    public var databaseTableName: String { get }
  • group(_:) Extension method

    Creates an association grouped according to expressions promise.

    Declaration

    Swift

    public func group(_ expressions: @escaping (Database) throws -> [SQLExpressible]) -> Self
  • having(_:) Extension method

    Creates an association with the provided predicate promise added to the eventual set of already applied predicates.

    Declaration

    Swift

    public func having(_ predicate: @escaping (Database) throws -> SQLExpressible) -> Self
  • distinct() Extension method

    Creates an association for returns distinct rows.

    Declaration

    Swift

    public func distinct() -> Self
  • with(_:) Extension method

    Returns an association that embeds the common table expression.

    See QueryInterfaceRequest.with(_:) for more information.

    Declaration

    Swift

    public func with<RowDecoder>(_ cte: CommonTableExpression<RowDecoder>) -> Self