在Slick中过滤和混合monad以获得理解和Cats

时间:2016-05-19 21:29:08

标签: scala functional-programming monads slick scala-cats

我有以下目标: 创建一个monad,为用户添加以下计算流程:

  1. 检查用户是否存在指定的电子邮件,如果他不那么:
  2. 检查提供的凭据是否正常(密码足够长等)。如果他们没问题,那么:
  3. 将用户保存到数据库
  4. 我的第一个"草案"会是这样的:

    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
    

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

1 个答案:

答案 0 :(得分:2)

这个不用于理解,所以让我知道这是否可以接受。

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
}