Объедините несколько соединений с фильтрами в Vapor - PullRequest
1 голос
/ 23 марта 2019

В моем бэкэнде у меня есть Post s и PostController. Сообщение может быть visibleToFriendOnly.
В GET /posts я хочу вернуть все сообщения, которые может просматривать текущий пользователь.
Модель User имеет свойство friends, то есть стержень User, User со столбцами userID и friendID.

В настоящее время я получаю сообщения, подобные этому:

/// /posts
func all(req: Request) throws -> Future<[Post]> {
    let authenticated = try req.requireAuthenticated(User.self)
    return Post.query(on: req)
        .filter(\Post.visibleForUserType == authenticated.type)
        // FIXME: respect .visibleForFriendsOnly
        .all()
}

Мне трудно с этим, потому что для каждого Post мне нужно было бы получить userID, а затем User (кто автор), а затем запросить пользователя friends и посмотрите, есть ли текущий пользователь в этом списке.
Есть ли реальный способ сделать это? Может быть, соединение или что-то?

1 Ответ

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

Похоже, вы могли бы создать собственный необработанный запрос, подобный этому

return req.requestPooledConnection(to: .mysql).flatMap { conn in
    defer { try? req.releasePooledConnection(conn, to: .mysql) }
    return conn.raw("""
    SELECT posts.* FROM posts
    LEFT OUTER JOIN user_friends
        ON (user_friends.userID = posts.userID AND user_friends.friendID = 3)
        OR (user_friends.friendID = posts.userID AND user_friends.userID = 3)
    GROUP BY posts.id
    HAVING COUNT(user_friends.id) = 2 OR posts.userID = 3 OR visibleForFriendsOnly = 0
    """).all(decoding: Post.self)
}
...