I'm looking for a way to use two different forms for one case class. I was trying to do that with additional constructor, but failed with that. Look at the code snippet:
case class LoginDetails(password: String, field3: Option[Int], field4: String)
case class User(username: String, loginDetails: LoginDetails) {
def this(username: String, password: String, field3: Option[Int], field4: String) = this(username, LoginDetails(password, field3, field4))
// some logic inside
}
val loginDetailsForm = Form(
mapping(
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(LoginDetails.apply)(LoginDetails.unapply))
val oldForm = Form(
mapping(
"username" -> email,
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(User.apply)(User.unapply))
val newForm = Form(
mapping(
"username" -> email,
"loginDetails" -> loginDetailsForm.mapping
)(User.apply)(User.unapply))
What I'm trying to do is to support two API's (new and old one), but if I will have two copies of the same case class, I will have to make code logic duplicates in many many places in the rest of the code. If there is a way to do that?
Of course given code doesn't work and is used like an example.
Thanks!
You could try to add methods applyOld
and unapplyOld
to companion object like this:
case class User(username: String, loginDetails: LoginDetails)
object User {
def applyOld(username: String, password: String, field3: Option[Int], field4: String) = new User(username, LoginDetails(password, field3, field4))
def unapplyOld(u: User): Option[(String, String, Option[Int], String)] =
Some((u.username, u.loginDetails.password, u.loginDetails.field3, u.loginDetails.field4))
}
You just need methods (String, String, Option[Int], String) => User
and User => Option[(String, String, Option[Int], String)]
, you could place them anywhere you like. For instance you could create object UserOld
with methods apply
and unapply
.
Usage:
val oldForm = Form(
mapping(
"username" -> email,
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(User.applyOld)(User.unapplyOld))
val newForm = Form(
mapping(
"username" -> email,
"loginDetails" -> loginDetailsForm.mapping
)(User.apply)(User.unapply))
You can do the apply/unapply directly where the form is defined instead. Then you don't have to add any new constructors to the case class.
val oldForm = Form(
mapping(
"username" -> email,
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(
(username, password, field3, field4) =>
User(username, LoginDetails(password, field3, field4))
)(
(user: User) =>
Option(user.username, user.loginDetails.password, user.loginDetails.field3, user.loginDetails.field4)
)
)
val newForm = Form(
mapping(
"username" -> email,
"loginDetails" -> loginDetailsForm.mapping
)(User.apply)(User.unapply))