Reputation: 105
I have the following objective: Create a monad that adds an user with the following computation flow:
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.
Upvotes: 2
Views: 1084
Reputation: 4471
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
}
Upvotes: 3