I have the following piece of code I'd like to make DRYer:
def createAdmin(/* ... */): Future[Int] =
db.run {
{
(users returning users.map(_.id)) += Account(0, /* ... */)
} flatMap { id =>
admins += Admin(userId = id, /* ... */)
}
}
def createStandardUser(/* ... */): Future[Int] =
db.run {
{
(users returning users.map(_.id)) += Account(0, /* ... */)
} flatMap { id =>
standardUsers += StandardUser(userId = id, /* ... */)
}
}
That compiles fine. But if I consolidate the two into the following:
def createUser(role: String)(/* ... */): Future[Int] =
db.run {
{
(users returning users.map(_.id)) += Account(0, /* ... */)
} flatMap { id =>
role match {
case "admin" =>
admins += Admin(userId = id, /* ... */)
case "standard" =>
standardUsers += StandardUser(userId = id, /* ... */)
}
}
}
I get the following type mismatch error:
[error] found : Long => slick.dbio.DBIOAction[Int,slick.dbio.NoStream,Nothing]
[error] required: Long => slick.dbio.DBIOAction[Int,slick.dbio.NoStream,E2]
[error] } flatMap { id =>
[error] ^
[error] one error found
I can't seem to figure out why. Can someone illuminate this for me?
The compiler can't figure out the used effect type correctly. As a workaround you should be able to give it some help by specifiying types used, e.g. in the flatMap operation, which would be
flatMap[Int, NoStream, Effect.Write] { id =>
in your case.
I am afraid you can't refactor the code that way.
I know that from the point of view of the code it looks reasonable. But the pattern matching in the flatMap
doesn't give enough information to the compiler to infer the effect to the DBIOAction.
As you can read in the source code:
When composing actions, the correct combined effect type will be inferred
So in other words, as Slick doesn't know what are you going to do after the first insertion in compilation time, the compilation fails. And as the documentation says, "it is not possible to fuse this actions for more efficient execution".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With