Play Framework documentation for Scala shows a sample mapping a form to a case class implicitly:
case class User(name: String, age: Int)
val userForm = Form(
mapping(
"name" -> text,
"age" -> number
)(User.apply)(User.unapply)
)
We notice that only primitive values are used in this unique sample.
How about if we make this alteration:
case class Car(brandName: String)
case class User(name: String, car: Car)
Moreover, let's assume that the form returns the User's name (String) and a carId(String)
val userForm = Form(
mapping(
"name" -> text,
"car" -> carRepository.findById(nonEmptyText) // concept I wish
)(User.apply)(User.unapply)
)
Is there any way to instantiate a car at this wished line with some carId provided for example by the form and ensuring also that the carId is not an empty String?
For first part of your question, documentation also shows Nested values:
case class Car(brandName: String)
case class User(name: String, car: Car)
val userForm = Form(
mapping(
"name" -> text,
"car" -> mapping(
"brandName" -> text
)(Car.apply)(Car.unapply)
)(User.apply, User.unapply)
)
You could supply a Formatter and use the of[Car] method.
implicit val carFormat = new Formatter[Car] {
def bind(key: String, data: Map[String, String]):Either[Seq[FormError], Car] =
data.get(key)
// make sure the method returns an option of Car
.flatMap(carRepository.findByBrandName _)
.toRight(Seq(FormError(key, "error.carNotFound", Nil)))
def unbind(key: String, value: Car) = Map(key -> value.brandName)
}
This answer provides another Formatter: Play 2 - Scala - Forms Validators and radio buttons
You can then use it like this:
val userForm = Form(
mapping(
"name" -> text,
"car" -> of[Car]
)(User.apply)(User.unapply)
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With