Filtering and mixing monads in Slick for comprehension and Cats

筅森魡賤 提交于 2019-12-11 02:02:05

问题


I have the following objective: Create a monad that adds an user with the following computation flow:

  1. Check if an user exists with a specified e-mail, if he doesn't then :
  2. Check if the credentials given are ok (password long enough, etc.). If they are ok, then:
  3. Save the user to the DB

My first "draft" would be something like this:

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

Any ideas what is the best way to write this down in one monadic computation that I can db.run(...)? I'm using Cats + Slick 3.0. Also I've wrote a simple implicit dbioMonad from https://groups.google.com/forum/?fromgroups#!topic/scalaquery/HrvrvyEIopw if that helps.


回答1:


This one doesn't use for comprehension, so let me know if that's acceptable.

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
}


来源:https://stackoverflow.com/questions/37334335/filtering-and-mixing-monads-in-slick-for-comprehension-and-cats

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!