#mysql #swift #join #vapor
#mysql #swift #Присоединиться #vapor
Вопрос:
В моем бэкэнде у меня есть Post
s и a 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. Я бы посоветовал попробовать запросить необходимые данные в одном запросе, используя raw query, тогда вы поймете, возможно ли это с Fluent или вам нужно что-то большее
2. Не могли бы вы показать какой-нибудь код? Я относительно новичок в Vapor и во всем, что касается серверной части / базы данных, особенно объединений… @imike
3. вы могли бы найти меня в Discord как имайк #3049
Ответ №1:
Похоже, вы могли бы создать пользовательский необработанный запрос, подобный этому
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)
}