简体   繁体   English

查询在Vapor中如何工作?

[英]How query works in Vapor?

How to return user if based on facebook user ID it already exist, and create a new user if not exist in Vapor ? 如果基于facebook用户ID已经存在,如何返回用户,如果Vapor不存在,如何创建新用户? You can see how I tried fetch data, but get error. 您可以看到我如何尝试获取数据,但会出错。

final class User: Content {
    var id: Int?
    var fbId: String

    init(id: Int? = nil, fbId: String) {
        self.id = id
        self.fbId = fbId
    }
}

router.get("user") { (request) -> Future<User> in
    return Future.map(on: request) { () -> User in
        let fbId = try request.query.get(String.self, at: "fbId")
        return User.query(on: request).filter(\.fbId == fbId).first().map { (user) -> (U) in
            if user == nil {
                user = User(fbId: fbId)
            }
            return user
        }
    }
}

在此处输入图片说明

You have a few things going on here. 您正在这里进行几件事。 To start with you don't need the first Future.map - not sure what that's doing. 首先,您不需要第一个Future.map不确定正在做什么。

Then you have the issue of the compiler - you have to return the same type in each closure and the function, which is awkward because if you already have a user you can return that, if you don't you need to create and save one, which returns Future<User> , which is not the same to User . 然后是编译器的问题-必须在每个闭包和函数中返回相同的类型,这很尴尬,因为如果您已经有一个用户,则可以返回该类型,如果不需要,则需要创建并保存一个,它返回Future<User> ,它与User

So to answer your question, U there should be User , but really you want to change first().map to first().flatMap in which case U becomes Future<User> . 因此,要回答您的问题, U应该有User ,但实际上您想将first().map更改为first().flatMap在这种情况下, U成为Future<User> Then you can do something like: 然后,您可以执行以下操作:

router.get("user") { req -> Future<User> in
    let fbID = try req.query.get(String.self, at: "fbId")
    return User.query(on: req).filter(\.fbId == fbID).first().flatMap { user in
        let returnedUser: Future<User>
        if let foundUser = user {
            returnedUser = req.future(foundUser)
        } else {
            let newUser = User(fbId: fbID)
            returnedUser = newUser.save(on: req)
        }
        return returnedUser
    }
}

To solve your problems. 解决您的问题。 Hope that helps! 希望有帮助!

.map { (user) -> (U) in

This defines that you get a user into the closure and have to return a U . 这定义您将user带到闭包中并且必须返回U In your example you want to return a User (so change U to User ). 在您的示例中,您想返回一个User (因此将U更改为User )。

If you want to create the user (in case it is nil ) you probably also want to store it in the database? 如果要创建用户(如果为nil ),则可能还希望将其存储在数据库中? If that's the case, you'll have to change map to flatMap and update like this: 如果是这种情况,则必须将map更改为flatMap并进行如下更新:

.flatMap { (user) -> EventLoopFuture<User> in
  if user == nil {
    return User(fbId: fbId).save(on: req)
  }
  return req.future(user)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM