这里的诀窍是定义一个Constraint
类似这个例子的自定义类型。Constraint
然后可以使用自定义方法Mapping[T]
来验证表单中的字段verifying
。
自定义Constraint
包含返回 aValidationResult
或Valid
的逻辑Invalid
。可以将错误消息传递给Invalid
结果,您可以在其中指定数据库中重复或存在的内容。
有关自定义验证的部分,请参阅Play for Scala。
- 创建约束
//Make this lazy to prevent java.lang.ExceptionInInitializerError at runtime.
lazy val uniqueNumbersConstraint = Constraint[String](Some("Unique numbers constraint"), "")(checkNumbers)
//"Business Logic".
//Important part here is that the function returns a ValidationResult and complies with the signature for Constraint. i.e. f: (T) => ValidationResult
//Return Valid if n in numbers is not in database and there are no duplicates.
//Otherwise return Invalid and an error message showing what numbers are in the database or duplicated.
def checkNumbers(numbers: String):ValidationResult = {
val splitNums = numbers.split(" ").toList.map(_.toInt)
val dbnums = splitNums.partition(database.contains(_))
if(dbnums._1.isEmpty && uniquesAndDuplicates(splitNums)._2.isEmpty){
Valid
}else{
val duplicates = uniquesAndDuplicates(dbnums._2)._2
val error = "Database contains: " + dbnums._1 + ", duplicated values: " + duplicates
Invalid(error)
}
}
- 使用自定义约束验证表单
val helloForm = Form(
tuple(
"numbers" -> nonEmptyText.verifying(uniqueNumbersConstraint)
))
- 实用程序
//Return unique values on left side and duplicate values on right side
def uniquesAndDuplicates(numbers: List[Int]):Tuple2[List[Int], List[Int]] = {
numbers.partition(i => numbers.indexOf (i) == numbers.lastIndexOf(i))
}
def checkNum(num: Int) = {
database.contains(num)
}
val database = List(5,6,7)
- ETC
注意我在表格中定义numbers
为a String
。当我将它定义为list(number)
它不断评估为List()
. 我认为这是一个有约束力的问题。这是一个相当简单的更改来使用List(1,2,3)
而不是"1 2 3"
如果使用list(number)
作品。
- 样品