I have a trait and two case classes that extends it:
trait Authenticatable {
val email: String
val pass: String
val id: Long
val sessionid: String
}
case class Admin(
id: Long,
email: String,
pass: String,
sessionid: Option[String] = None) extends Authenticatable
case class Client(
id: Long,
email: String,
pass: String,
sessionid: Option[String] = None) extends Authenticatable
And I have functions witch should authenticate user, make copy of object with new sessionid and return it.
def auth(email: String, password: String): Try[Admin] ={
checkPass(models.Admin.findBy(sqls"email = $email"), password)
}
def auth(email: String, password: String, customer: Customer): Try[Customer] ={
checkPass(models.Customer.findBy(sqls"email = $email"), password)
}
private def checkPass (model: Option[Authenticatable], password: String): Try[Authenticatable]={
model match {
case Some(m) => check(password, m.pass).map(_ => m)
case _ => Failure(new Exception("Authentication failure!"))
}
}
The problem is: I can't make copy of object in auth function because function checkPass returns Authenticatable and not Client or Admin class and Authenticatable doesn't have copy method of case classes.
What is the right way to solve this problem?
If you use type parameters, you can avoid throwing away the information that checkPass
will always return the same type of Authenticable
as was given to it:
private def checkPass[A <: Authenticatable](model: Option[A], password: String): Try[A] =
// exactly the same body here
This means that in auth
you can have eg:
def auth(email: String, password: String): Try[Admin] =
checkPass(models.Admin.findBy(sqls"email = $email"), password)
.map(_.copy(sessionid = Some("whatever")))
I would propose to add an abstract method to Authenticable
which sets session ID and which is implemented by individual case classes by using of the generated copy
method.
trait Authenticable {
def email: String
def pass: String
def id: Long
def sessionid: Option[String]
def setSessionId(id: String): Authenticable
}
case class Admin(
id: Long,
email: String,
pass: String,
sessionid: Option[String] = None) extends Authenticable {
def setSessionId(id: String) = copy(sessionid = Some(id))
}
case class Client(
id: Long,
email: String,
pass: String,
sessionid: Option[String] = None) extends Authenticable {
def setSessionId(id: String) = copy(sessionid = Some(id))
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.