在 Slick 中过滤和混合 monads for comprehension 和 Cats

Filtering and mixing monads in Slick for comprehension and Cats

我有以下 objective: 使用以下计算流程创建一个添加用户的 monad:

  1. 检查是否存在具有指定电子邮件的用户,如果他不存在则:
  2. 检查给定的凭据是否正确(密码足够长等)。如果他们没问题,那么:
  3. 将用户保存到数据库

我的第一个 "draft" 会是这样的:

val work: DBIO[UserId] = for {
   userO <- UserRepository.findByEmail(createdUser.email) //userO is Option[User]
   //This won't work cause Action.withFilter doesnt exist
   if userO.isEmpty 
   //as above, validate user actually returns an ValidateNel[String, User]
   if User.validateUser(createdUser.email, createdUser.password).isValid 
   //Returns DBIO[UserId]
   id <- UserRepository.save(createdUser)
} yield id

任何想法是什么是我可以 db.run(...) 在一个一元计算中写下它的最佳方法?我正在使用 Cats + Slick 3.0。 如果有帮助,我还从 https://groups.google.com/forum/?fromgroups#!topic/scalaquery/HrvrvyEIopw 写了一个简单的隐式 dbioMonad。

这个不能用于理解,如果可以接受请告诉我。

val work: DBIO[UserId] = {
  UserRepository.findByEmail(createdUser.email).flatMap {
    case Some(_) => DBIO.failed(new Exception("Provided email is already taken"))
    case _ =>
      if(User.validateUser(createdUser.email, createdUser.password).isValid) {
        UserRepository.save(createdUser)
      } else {
        DBIO.failed(new Exception("User validation has failed"))
      }
  }.transactionally
}