蒸气4流利。复杂的查询,过滤并创建(如果不存在)

问题描述 投票:0回答:1

我正在尝试与两个用户聊天。如果存在,我想退还它。如果不是,我想与这两个用户建立新的聊天并返回。

注释显示如果聊天存在,它将失败。

如果在这种情况下,您可以显示如何与这两个用户创建新的聊天,这也将有所帮助。

func create(req: Request) throws -> EventLoopFuture<Chat> {

    let currentUser = try req.auth.require(User.self)

    guard
      let userID = req.parameters.get("userID"),
      let uuid = UUID(userID)
      else { throw Abort(.badRequest) }

    return User
      .query(on: req.db)
      .filter(\.$id == uuid)
      .with(\.$chats)
      .first()
      .unwrap(or: Abort(.internalServerError))
      .flatMap({ chatUser -> EventLoopFuture<Chat> in

        let chat = chatUser
          .chats
          .filter({
            $0.users.contains(where: { $0.id == currentUser.id }) // FAILS HERE: Fatal error: Siblings relation not eager loaded, use $ prefix to access: Siblings<Chat, User, ChatUser>(from: [chat_id], to: [user_id]): file
          })
          .first

        if let chat = chat {

          return req
            .eventLoop
            .makeSucceededFuture(chat)

        } else {

          // create new chat with those two users and return

        }
      })
}

简化模型:

final class Chat: Model, Content {

  @ID(key: .id)
  var id: UUID?

  @Siblings(through: ChatUser.self, from: \.$chat, to: \.$user)
  var users: [User]

}

final class User: Model, Content {

  @ID(key: .id)
  var id: UUID?

  @Siblings(through: ChatUser.self, from: \.$user, to: \.$chat)
  var chats: [Chat]
}
vapor vapor-fluent
1个回答
0
投票

您的问题是,从根本上讲,您需要对User模型中使用的ChatUser模型进行进一步的加载。如果可能的话,在您的第一个查询以及.with(\.$chats)中,您将执行类似.with(\.$chats.$chats)的操作,但这是不可能的。

在这种情况下,不是建议直接回答您的问题,我是否建议您考虑开始对ChatUser的查询?如果您在此Model中查找匹配的记录,然后进行相应的工作。类似于:

ChatUser.query(on:req.db).filter(\.$id == currentUser.id).filter(\.$chat).first().map
{
    mayExist in
    if let doesExist = mayExist
    {
        // work with existing chat
    }
    else
    {
        // does not exist so create a new one
    }
}

PS-急着去上班,所以这里可能有很多漏洞!

© www.soinside.com 2019 - 2024. All rights reserved.