Louis F.
Louis F.

Reputation: 2048

Default value in case class, Play Form

I have the following case class:

case class User(id:String = UUID.random().toString, name:String)

And the following creation form :

val userForm = Form(
    mapping(
      "name" -> text
    )(User.apply)(User.unapply)
  )

But then the Form is complaining about the apply / unapply function not having enough arguments (the id is missing). Is there any workaround in order not to rewrite all the apply / unapply functions of the case classes and using the default value of the case class ?

Of course this is an example, and my real case is more complex with nested lists of case classes so I would really like to use the 'automatic' case class mapping !

Upvotes: 0

Views: 495

Answers (3)

Kolmar
Kolmar

Reputation: 14224

You can extend on @m-z's solution, and transform the ignored value to produce a random UUID every time:

val userForm = Form(
  mapping(
    "id" -> ignored(()).transform[String](
      _ => UUID.random().toString,
      _ => ()),
    "name" -> text
  )(User.apply)(User.unapply)
)

Also, although you have remarked that you don't to rewrite the apply and unapply, I think in some cases it might still be a possibility as well:

val userForm2 = Form(
  mapping(
    "name" -> text
  )(n => User(name = n))(u => User.unapply(u).map(_._2))
)

Upvotes: 2

millhouse
millhouse

Reputation: 10007

Rather than a random and meaningless UUID as a default ID, I like to use an Option[String] for model classes; e.g.:

case class User(id:Option[String], name:String)

Then you can use the optional mapping:

val userForm = Form(
  mapping(
    "id" -> optional(text),
    "text" -> text,
  )
)

and fold (or match, whatever you like) on the id when the form is submitted back to you, perhaps generating the UUID at that time.

Benefits of doing it this way:

  • It's completely obvious whether a form has been populated from defaults
  • You can re-use the form for "update my profile"-type operations where the ID is populated

Upvotes: 0

Michael Zajac
Michael Zajac

Reputation: 55569

You can use ignored:

val userForm = Form(
   mapping(
     "id" -> ignored(UUID.random()),
     "name" -> text
  )(User.apply)(User.unapply)
)

Upvotes: 1

Related Questions