Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework 2.1 / form mapping with complex objects

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?

like image 216
Mik378 Avatar asked Nov 24 '25 14:11

Mik378


2 Answers

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)
)
like image 65
trappedIntoCode Avatar answered Nov 27 '25 15:11

trappedIntoCode


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)
)
like image 40
EECOLOR Avatar answered Nov 27 '25 15:11

EECOLOR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!