Vapor 中相同模型之间的兄弟姐妹关系

Siblings relationship between same models in Vapor

我有一个 User 模型,我想在其中添加一个 friends 属性。朋友,应该是其他Users.

我创建了 UserFriendsPivot:

final class UserFriendsPivot: MySQLPivot, ModifiablePivot {
    var id: Int?
    var userID: User.ID
    var friendID: User.ID

    typealias Left = User
    typealias Right = User

    static var leftIDKey: WritableKeyPath<UserFriendsPivot, Int> {
        return \.userID
    }

    static var rightIDKey: WritableKeyPath<UserFriendsPivot, Int> {
        return \.friendID
    }

    init(_ user: User, _ friend: User) throws {
        self.userID   = try user  .requireID()
        self.friendID = try friend.requireID()
    }
}

extension UserFriendsPivot: Migration {
    public static var entity: String {
        return "user_friends"
    }
}

我将 friends 属性 添加到 User:

var friends: Siblings<User, User, UserFriendsPivot> {
    return siblings()
}

现在,我在 return siblings() 行中看到以下错误:

Ambiguous use of 'siblings(related:through:)'

我尝试将其替换为:

return siblings(related: User.self, through: UserFriendsPivot.self)

...运气不好。

我知道这两个代码片段 应该 有效,因为我直接从我在 EventUser 之间建立的另一个兄弟姐妹关系中复制了它们那工作得很好。
我看到的唯一区别是我正在尝试在相同模型之间建立关系。

我能做什么?

尝试用类似以下内容替换您的 friends 定义:

var friends: Siblings<User,UserFriendsPivot.Right, UserFriendsPivot> {
    return User.siblings()
}

编辑:

它应该像 table 一样与 LeftRight 一起工作,但似乎失败了,因为别名解析为基值。 IE。 Xcode 中的自动完成显示 siblings 的所有候选者最终都属于以下类型:

Siblings<User, User, UserFriendsPivot> siblings(...)

而不是:

Siblings<User, UserFriendsPivot.Right, UserFriendsPivot> siblings(...)

和类似的。

我建议在 GitHub 上提出错误。同时,如何使用不同的名称和设置创建 User 的副本:

static let entity = "User"

使用相同的物理 table。不漂亮,但它可能会让你工作。

这里的问题是,在同一个 Model (User-User) 兄弟姐妹关系中,Fluent 无法推断你指的是哪个兄弟姐妹——需要指定双方。

extension User {
    // friends of this user
    var friends: Siblings<User, User, UserFriendsPivot> {
        siblings(UserFriendsPivot.leftIDKey, UserFriendsPivot.rightIDKey)
    }

    // users who are friends with this user
    var friendOf: Siblings<User, User, UserFriendsPivot> {
        siblings(UserFriendsPivot.rightIDKey, UserFriendsPivot.leftIDKey)
    }
}

另一个相同的-Model后果是您将无法使用附加便捷方法添加到数据透视表table,而需要手动创建:

let pivot = try UserFriendsPivot(user, friend)
pivot.save(on: req)

(还有其他方法可以解决这个问题,我只是发现上面这些简单的方法最容易使用。指定边和反转关键位置以获得反比关系是重要的概念。)


grundoon

回答