使用 Fluent 的 Vapor 3 中的多对多关系

Many-to-Many relations in Vapor 3 with Fluent

我想知道如何使用 Fluent 和 FluentMySQL 在 Vapor 3 中创建多对多关系,如 Vapor 2 docs

中所述

遗憾的是,docs for Vapor 3 尚未更新,Pivot 协议的实施已更改。

这是我正在尝试做的事情:我有两个 类、UserCommunity。一个 Communitymembers 并且 User 可以是多个 Community 的成员。

目前,我的代码如下所示:

import Vapor
import FluentMySQL

final class Community: MySQLModel {
    var id: Int?
    //Community Attributes here
}

final class User: MySQLModel {
    var id: Int?
    //User Attributes here
}

extension Community {
    var members: Siblings<Community, User, Pivot<Community, User>> {
        return siblings()
    }
}

但是,这会导致以下编译器错误:

Cannot specialize non-generic type 'Pivot'Using 'Pivot' as a concrete type conforming to protocol 'Pivot' is not supported.

我看到有一个名为 ModifiablePivot 的协议扩展,但我不知道如何使用它,因为没有任何文档或示例代码。

感谢任何帮助。提前致谢!

Fluent 3 不再像 Fluent 2 中的 Pivot 那样提供默认枢轴。您应该做的是创建一个符合 Pivot 的类型。为此,FluentMySQL 中有一些辅助类型。

final class CommunityUser: MySQLPivot {
    // implement the rest of the protocol requirements
    var communityID: Community.ID
    var userID: User.ID
}

然后使用 CommunityUser 代替 Pivot<Community, User>

完整代码:

import Vapor
import FluentSQLite

final class Community: SQLiteModel {
    var id: Int?
    //Community Attributes here
}

final class User: SQLiteModel {
    var id: Int?
    //User Attributes here
}

extension Community {
    var members: Siblings<Community, User, CommunityUser> {
        return siblings()
    }
}

final class CommunityUser: SQLitePivot {
    typealias Left = User
    typealias Right = Community
    static let leftIDKey: LeftIDKey = \.userID
    static let rightIDKey: RightIDKey = \.communityID
    var id: Int?
    var userID: Int
    var communityID: Int
}

我遇到了同样的问题,两个答案对我来说都不够,所以我只是发布对我有用的解决方案。

// in CommunityUser.swift
import Vapor
import FluentMySQL


final class CommunityUser: MySQLPivot {

    typealias Left = User
    typealias Right = Community

    static var leftIDKey: LeftIDKey = \.userID
    static var rightIDKey: RightIDKey = \.communityID

    var id: Int?
    var userID: Int
    var communityID: Int

    init(id: Int?, userID: Int, communityID: Int) {
        self.id = id
        self.userID = userID
        self.communityID = communityID
    }

}

// CommunityUser didn't conform to MySQLMigration
// This simple line solves the problem
extension CommunityUser: MySQLMigration { }

对我来说CommunityUser 也需要在数据库中迁移。

// in configure.swift
migrations.add(model: CommunityUser.self, database: .mysql)