Отношения братьев и сестер между одинаковыми моделями в Vapor - PullRequest
2 голосов
/ 16 марта 2019

У меня есть модель User, к которой я хочу добавить свойство friends.Друзья, должны быть другими User s.

Я создал 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():

Неоднозначное использование «родных братьев (связанных: через:)»

Я пытался заменить его на:

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

... безуспешно.

Я знаю, что два фрагмента кода должны работать, потому что я прямскопировал их из других отношений между братьями и сестрами, которые я установил между Event и User, которые работают просто отлично.
Единственное отличие, которое я вижу, состоит в том, что я пытаюсь построить отношения между теми же моделями.

Что я могу сделать?

Ответы [ 2 ]

1 голос
/ 19 марта 2019

Проблема здесь в том, что в одном и том же - Model (User-User) отношении братьев и сестер, Fluent не может определить, какого брата вы имеете в виду - стороны должны быть указаны.

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

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

Другое то же самое - Model следствие заключается в том, что вы не сможете использовать удобный метод присоединения для добавления в сводную таблицу, и вам придется вместо этого создать вручную:

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

(Есть и другие подходы, чтобы обойти это, я просто нахожу эти простые способы выше простых в использовании. Определение сторон и смена ключевых позиций для получения обратного соотношения являются важными понятиями.)


в ответе grundoon

1 голос
/ 17 марта 2019

Попробуйте заменить определение friends на что-то вроде:

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

РЕДАКТИРОВАТЬ:

Он должен работать с Left и Right в той же таблице, но кажетсяпотерпеть неудачу, потому что псевдонимы разрешают к базовым значениям.Т.е. автозаполнение в Xcode показывает, что все кандидаты на siblings все имеют тип:

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

Вместо:

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

и аналогичных.

Iпредложил бы поднять ошибку на GitHub.А пока, как насчет создания копии User с другим именем и настройкой:

static let entity = "User"

для использования той же физической таблицы.Не очень, но это может заставить тебя работать.

...