Vapor 3 - 如何在保存对象之前检查类似的电子邮件

2024-04-05

我想创建一条路线来让用户更新他们的数据(例如更改他们的电子邮件或用户名)。为了确保用户不能使用与其他用户相同的用户名,我想检查数据库中是否已存在具有相同用户名的用户。

我已经使用户名在迁移中唯一。

我有一个如下所示的用户模型:

struct User: Content, SQLiteModel, Migration {
    var id: Int?
    var username: String
    var name: String
    var email: String
    var password: String

    var creationDate: Date?

    // Permissions
    var staff: Bool = false
    var superuser: Bool = false

    init(username: String, name: String, email: String, password: String) {
        self.username = username
        self.name = name
        self.email = email
        self.password = password
        self.creationDate = Date()
    }
}

这是我想使用它的代码片段:

func create(_ req: Request) throws -> EventLoopFuture<User> {
    return try req.content.decode(UserCreationRequest.self).flatMap { userRequest in

        // Check if `userRequest.email` already exists
        // If if does -> throw Abort(.badRequest, reason: "Email already in use")
        // Else -> Go on with creation

        let digest = try req.make(BCryptDigest.self)
        let hashedPassword = try digest.hash(userRequest.password)
        let persistedUser = User(name: userRequest.name, email: userRequest.email, password: hashedPassword)

        return persistedUser.save(on: req)
    }
}

我可以这样做(参见下一个片段),但这似乎是一个奇怪的选择,因为当更多检查时,例如,它需要大量嵌套。必须执行唯一性(例如在更新用户的情况下)。

func create(_ req: Request) throws -> EventLoopFuture<User> {
    return try req.content.decode(UserCreationRequest.self).flatMap { userRequest in
        let userID = userRequest.email
        return User.query(on: req).filter(\.userID == userID).first().flatMap { existingUser in
            guard existingUser == nil else {
                throw Abort(.badRequest, reason: "A user with this email already exists")
            }

            let digest = try req.make(BCryptDigest.self)
            let hashedPassword = try digest.hash(userRequest.password)
            let persistedUser = User(name: userRequest.name, email: userRequest.email, password: hashedPassword)

            return persistedUser.save(on: req)
        }
    }
}

正如其中一个答案所建议的那样,我尝试添加错误中间件(请参阅下一个片段),但这并不能正确捕获错误(也许我在代码中做错了什么 - 刚刚从 Vapor 开始)。

import Vapor
import FluentSQLite

enum InternalError: Error {
    case emailDuplicate
}

struct EmailDuplicateErrorMiddleware: Middleware {
    func respond(to request: Request, chainingTo next: Responder) throws -> EventLoopFuture<Response> {
        let response: Future<Response>

        do {
            response = try next.respond(to: request)
        } catch is SQLiteError {
            response = request.eventLoop.newFailedFuture(error: InternalError.emailDuplicate)
        }

        return response.catchFlatMap { error in
            if let response = error as? ResponseEncodable {
                do {
                    return try response.encode(for: request)
                } catch {
                    return request.eventLoop.newFailedFuture(error: InternalError.emailDuplicate)
                }
            } else {
                return request.eventLoop.newFailedFuture(error: error)
            }
        }
    }
}

快速的方法是做类似的事情User.query(on: req).filter(\.email == email).count()并在尝试保存之前检查它是否等于 0。

然而,虽然这对几乎每个人来说都可以正常工作,但您仍然面临边缘情况,即两个用户尝试在完全相同的时间使用相同的用户名注册 - 处理此问题的唯一方法是捕获保存失败,检查是否是因为电子邮件的唯一约束并将错误返回给用户。然而,即使对于大型应用程序,真正实现这一目标的机会也非常罕见。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vapor 3 - 如何在保存对象之前检查类似的电子邮件 的相关文章

随机推荐

  • 无法再卸载 Visual Studio 2017

    我在运行最新的 VS2017 时遇到了严重的问题 因为在我升级它时它进入了不一致的状态 有一些残留的软件包拒绝卸载 因为它们显然缺少来自的缓存文件C Windows Installer文件夹 我从来没有碰过那个文件夹 然而 我确实移动了C
  • 使用 InputMismatchException 进行尝试/捕获会创建无限循环[重复]

    这个问题在这里已经有答案了 所以我正在构建一个从用户输入中获取整数的程序 我有一个看起来非常简单的 try catch 块 如果用户没有输入 int 则应该重复该块直到他们输入 这是代码的相关部分 import java util Inpu
  • GWT 同步调用

    我在 GWT 中有一个方法 它使用请求的 fire 方法从数据库检索数据 因为你们都知道它是异步的 我从 JS 调用这个方法 所以我需要同步是否可能 private static String retriveLocation String
  • docker 镜像与 docker-desktop for windows 一起存储在哪里?

    I installed docker desktop for windows 10 from https www docker com products docker desktop https www docker com product
  • 备份远程SQL Server数据库到本地

    我正在尝试将实时数据库备份到我的计算机上 但找不到执行此操作的选项 我使用 Microsoft SQL Server Management Studio 2008 R2 连接到它 我是 MySQL 猴子 所以我习惯了能够备份到 sql文件并
  • 对象 TextField 内的模板标签

    我需要里面的自定义模板标签model TextField价值 对象文本字段中的值类似于 lorem ipsum dolor mytag 但 mytag 不会呈现为模板标签 它在库中注册为标签并加载到页面上 我有 object textfie
  • 在 Java 中用货币符号解析价格

    我想将我拥有的字符串解析为数字 这是我正在使用但不起作用的代码 NumberFormat getCurrencyInstance Locale GERMAN parse EUR 0 00 这会导致 java text ParseExcept
  • 百分号 (%) 在 Objective C 中的数学作用是什么?

    我非常困惑百分号在 Objective C 中的作用 有人能用像我这样的普通白痴能理解的语言向我解释吗 谢谢 是模运算符 因此例如 10 3 将得到 1 如果你有一些数字a and b a b只给你剩下的a除以b 所以在例子中10 3 10
  • 如何判断当前TD是否是TR中最后一个TD

    我有单行和多行 td 就在里面 在我的一个职能中 我遇到了一种情况 我必须找出我的currentSelectedTD是最后一个 td 放在行中 以便我可以以不同的方式对待它 I tried currentSelectedTD is last
  • Html 文本悬停在每个单词上进行翻译

    您好 我有一个 HTML 页面 其中包含文本正文 我希望能够将鼠标悬停在文本中的单词上 然后一小朵云显示文本中该单词的翻译 知道我该怎么做吗 我将提供我需要知道哪种是在悬停时将每个单词从文本中分离出来的最佳方法 并使用单词或翻译列表进行检查
  • 如何在 ConstraintLayout 中显示 GoogleMap?

    我创建了一个新项目 MapsActivity 我从 Google 获取了 API 密钥 并将 API 密钥放置在 YOUR KEY HERE 区域内的 google maps API xml debug 中 我在 AndroidManife
  • 泛型方法的可重用非泛型方法

    我有以下基本界面 public interface IHandler void Handle IMessage message 以及继承基接口的通用接口 public interface IHandler
  • 基于 OpenID 的 SSO 和 WSO2 身份服务器

    无法使用 WSO2 身份服务器获得基于 OpenID 的 SSO 我关注了 Suresh Aththanayaka 给出的博客文章 但是进入后https localhost 9443 openid admin作为您的 OpenID 标识符
  • PHP 类中的错误处理

    嘿 这里有个问题要问你们 我有很多次为 PHP 中的类选择错误处理 例如 在 Ajax PHP 处理类中 我这样做 public function setError msg this gt errors msg public functio
  • ASP.net 必需字段验证器 VisualStudio 2012

    我正在使用 ASP net c 开发一个项目 我希望RequiredFieldValidator 检查我的文本框 我正在添加验证器 它在 Visual Studio 2010 中工作得很好 但是一旦我做了同样的事情 完全相同的事情 它就无法
  • 整数比较值的输出错误

    我有以下代码 public static void doIntCompareProcess int a 100 int b 100 Integer c 200 Integer d 200 int f 20000 int e 20000 Sy
  • 如何创建波浪形状 CSS?

    请参阅下图了解我正在尝试创建的内容 到目前为止 我有以下内容 但它需要更加 频繁 例如增加正弦波或余弦波的频率 wave position relative height 70px width 600px background e0efe3
  • SwiftUI 可从 NavigationView 向下搜索多个视图?

    我遇到了相关问题 searchable我想知道它是否与我的应用程序的视图层次结构有关 我可以找到的使用 Searchable 的示例说直接在 NavigationView 上使用它 并像这样显示它 var body some View Na
  • 如何对 React 组件的 shouldComponentUpdate 方法进行单元测试

    我有一个 React 组件 它实现了应该组件更新 https facebook github io react docs react component html shouldcomponentupdate方法 我想对其进行单元测试 理想情
  • Vapor 3 - 如何在保存对象之前检查类似的电子邮件

    我想创建一条路线来让用户更新他们的数据 例如更改他们的电子邮件或用户名 为了确保用户不能使用与其他用户相同的用户名 我想检查数据库中是否已存在具有相同用户名的用户 我已经使用户名在迁移中唯一 我有一个如下所示的用户模型 struct Use