我正在try 理解如何使用Vapor创建CRUD函数.first()似乎是可选的,但不能作为可选类型展开

func first() -> EventLoopFuture<Token?>

这是我的Token.swift美元

import Foundation
import Fluent
import Vapor

final class Token: Model {
  // 1
  static let schema = "tokens"

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

  // 3
  @Field(key: "token")
  var token: String

  @Field(key: "debug")
  var debug: Bool

  // 4
  init() { }

  init(token: String, debug: Bool) {
    self.token = token
    self.debug = debug
  }
}

这是我的TokenController.swift美元

import Foundation
import Fluent
import Vapor

struct TokenController {
    func create(req: Request) async throws -> HTTPStatus {
        let token = try req.content.decode(Token.self)
        try await token.create(on: req.db)
        return .created
    }
    
    func delete(req: Request) async throws -> HTTPStatus {
        guard let token = req.parameters.get("token") else {
            return .badRequest
        }
        
        try await Token.query(on: req.db)
            .filter(\.$token == token)
            .first()
        
        try await delete(req: req.db)

        return .noContent
    }

}

@available(macOS 12, *)
extension TokenController: RouteCollection {
    func boot(routes: RoutesBuilder) throws {
        let tokens = routes.grouped("token")
        tokens.post(use: create)
        tokens.delete(":token", use: delete)
    }
}

返回令牌可能不在那里,因此它应该是可选的,但我得到了熟悉的错误

Initializer for conditional binding must have Optional type, not 'EventLoopFuture<Token?>'

如果我对documentation的理解正确的话,我显然是在使用Async-AWait,而不是EventLoopFuture<>,除非可能在引擎盖下.

根据我正在学习的一篇教程,有人建议通过获取表中的第一行来删除行

func delete(req: Request) async throws -> HTTPStatus {
  guard let token = req.parameters.get("token") else {
    return .badRequest
  }

  guard let row = try await Token.query(on: req.db)
    .filter(\.$token == token)
    .first()
  else {
    return .notFound
  }

  try await row.delete(on: req.db)
  return .noContent
}

但这给了我与TOKEN相同的错误,包括row.delete(on:_)方法的另一个错误

Value of type 'EventLoopFuture<Token?>' has no member 'delete'

我遗漏了什么?

·倾倒在文档上 ·回顾我在教程中的步骤 ·屏住呼吸,直到电脑正常工作

推荐答案

您可能需要帮助编译器并强制其使用.first()的异步版本:

guard let row: Token = try await Token.query(on: req.db)
    .filter(\.$token == token)
    .first()

因为这些函数具有相同的签名,所以它偶尔可以 Select future 的版本,特别是在其他地方有错误的情况下

Swift相关问答推荐

VisionOS发送通知

如何使用swift宏生成一个带有关联值的枚举?

向文本元素添加背景色失败

从Firebase播放音频文件不起作用

在SwiftUI中绘制形状的路径后填充形状

为什么我不能在这个 Swift 间接枚举中返回 self ?

相互取消任务

将 ArgumentParser 与 Swift 并发一起使用

如何在不将变量转换为字符串的情况下判断变量在 Swift 中是否为 Optional(nil)?

如何让飞机与 RealityKit 中的物体相撞

在 struct 中的序列和非序列泛型函数之间进行 Select

使用 Async-Await 和 Vapor-Fluent 创建 CRUD 函数 - Swift 5.6

如何在填充上添加 if else 语句? SwiftUI

Vapor 4,如何按外键过滤?

更新我的 pod 导致 GoogleDataTransport Umbrella 标头出现错误

在 Swift 4 中,如何删除基于块的 KVO 观察者?

Swift:在子类中覆盖 == 导致仅在超类中调用 ==

你如何在 UIBarItem 中使用 setTitleTextAttributes:forState?

应用程序包不包含有效标识符

tableView 部分标题消失 SWIFT