Как указать сложные проверки формы в Play 2?

Я понимаю, как добавить простые проверки формы в Play 2, например nonEmptyText, но как бы реализовать более сложные проверки, такие как "по крайней мере одно из полей должно быть определено"? В настоящее время я бросаю исключение в свой объект модели, если он инициализируется всеми None s, но это создает неприятное сообщение об ошибке. Я бы предпочел получить приветственное сообщение об ошибке на странице формы.

Ответ 1

Вы можете вставить mappings/tuples в свое определение формы и добавить правила verifying при сопоставлении, под-отображении, кортеже и подтеке. Затем в ваших шаблонах вы можете получить ошибки с помощью form.errors("fieldname") для определенного поля или группы полей.

Например:

val signinForm: Form[Account] = Form(
    mapping(
        "name" -> text(minLength=6, maxLength=50),
        "email" -> email,
        "password" -> tuple(
            "main" -> text(minLength=8, maxLength=16),
            "confirm" -> text
        ).verifying(
            // Add an additional constraint: both passwords must match
            "Passwords don't match", password => password._1 == password._2
        )
    )(Account.apply)(Account.unapply)
)

Если у вас есть два разных пароля, вы можете получить ошибку в своем шаблоне, используя form.errors("password")

В этом примере вам нужно будет написать свои собственные Account.apply и Account.unapply для обработки (String, String, (String, String))

Ответ 2

Я улучшил принятый ответ @hheraud. Вы можете взять кортеж и преобразовать его обратно в одну строку. Это позволяет использовать функции apply/unapply по умолчанию.

Пример:

val signinForm: Form[Account] = Form(
    mapping(
        "name" -> text(minLength=6, maxLength=50),
        "email" -> email,
        "password" -> tuple(
            "main" -> text(minLength=8, maxLength=16),
            "confirm" -> text
        ).verifying(
            // Add an additional constraint: both passwords must match
            "Passwords don't match", password => password._1 == password._2
        ).transform(
            { case (main, confirm) => main },
            (main: String) => ("", "")
        )
    )(Account.apply)(Account.unapply)
)

Ответ 3

В игре! Framework, вы можете показывать дружественные сообщения об ошибках с помощью переменной вспышки. Вам просто нужно написать что-то вроде:

flash.error("Oops. An error occurred");

к вашему контроллеру. Если это сообщение об ошибке будет находиться на странице html, следует установить, например,:

<h1>${flash.error}</h1>

Играть! Framework разместит сообщение об ошибке, в котором обнаружит эту вещь ${flash.error}.