Scala Play表单验证:一个案例类的不同表单 - 是否可能?

时间:2013-06-03 12:27:06

标签: forms scala playframework mapping playframework-2.0

我正在寻找一种方法,为一个案例类使用两种不同的形式。我试图用额外的构造函数做到这一点,但失败了。请查看代码段:

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))

我要做的是支持两个API(新旧),但是如果我将拥有同一个案例类的两个副本,我将不得不在其他许多地方制作代码逻辑副本的代码。如果有办法做到这一点?

当然,给定的代码不起作用,并且像示例一样使用。

谢谢!

2 个答案:

答案 0 :(得分:5)

您可以尝试将方法applyOldunapplyOld添加到协同对象,如下所示:

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))
}

您只需要方法(String, String, Option[Int], String) => UserUser => Option[(String, String, Option[Int], String)],您可以将它们放在任何您喜欢的地方。例如,您可以使用方法UserOldapply创建对象unapply

用法:

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))

答案 1 :(得分:3)

您可以直接在定义表单的位置执行apply / unapply。然后,您不必向case类添加任何新的构造函数。

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))