Reputation: 2168
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!
Upvotes: 2
Views: 1013
Reputation: 48075
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))
Upvotes: 3
Reputation: 38045
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))
Upvotes: 5