2013-02-25 3 views
3

Play Framework документации по Scala показывает пример отображающую формы в случае класса неявно:Play Framework 2.1/форма отображения сложных объектов

case class User(name: String, age: Int) 

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

Мы замечаем, что только примитивные значения используются в этом уникальном образце.

Как насчет если мы делаем это изменение:

case class Car(brandName: String) 

case class User(name: String, car: Car) 

Кроме того, предположим, что форма возвращает User «s имя (String) и carId (String)

val userForm = Form(
    mapping(
    "name" -> text, 
    "car" -> carRepository.findById(nonEmptyText) // concept I wish 
)(User.apply)(User.unapply) 
) 

Есть каким-либо образом создать экземпляр автомобиля по этой желаемой строке с помощью некоторого carId, предоставленного, например, формой и гарантирующей, что carId не является пустым String?

ответ

5

Для первой части вашего вопроса, документация также показывает Вложенные значения:

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

Одно слово в моей голове ... «Стыд»:) Спасибо;) – Mik378

+1

Или два ... «Больше кофеина!» ;). YW. Хотя ответ EECOLOR ниже может решить обе проблемы. Сейчас я изучаю Formatter. – trappedIntoCode

+0

:) На самом деле ваше решение может решить обе проблемы с помощью метода 'verification' на вложенном сопоставлении, возвращающего' Constraint' и связанное с ним сообщение об ошибке. Таким образом, метод аргумента 'verifying' проверяет через базу данных' Car'. – Mik378

5

Вы можете поставить Formatter и использовать метод of[Car].

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

Этот ответ дает еще один Formatter: Play 2 - Scala - Forms Validators and radio buttons

Вы можете использовать его как это:

val userForm = Form(
    mapping(
    "name" -> text, 
    "car" -> of[Car] 
)(User.apply)(User.unapply) 
) 
+0

Очень приятное решение! – Mik378

+0

Я не понимаю, что вы имеете в виду. – EECOLOR

+0

Я имел в виду: «если бы я мог принять (зеленая галочка) оба ответа» – Mik378

2

Поздний приход к этому, но я только что выпустил утилиту, чтобы помочь с этим! Используя классы, ваш код будет выглядеть следующим образом:

case class Car(brandName: String) 
object Car { implicit val mapping = CaseClassMapping.mapping[Car] } 

case class User(name: String, car: Car) 
object User { implicit val mapping = CaseClassMapping.mapping[User] } 

val userForm = Form(implicitly[Mapping[User]]) 

Вы можете найти источник и инструкции для включения его в свой проект на GitHub: https://github.com/Iterable/iterable-play-utils

Смежные вопросы