How can I apply a Play 2 uniqueness validation onl

2019-05-06 23:18发布

问题:

How can I apply a Play 2 uniqueness validation only when an object is being created? I can add a custom verifying clause, but it would fail when editing (as opposed to creating) an existing objet.

回答1:

If you are not performing the same validation checks on edition and creation maybe it means that you should not use the same Form object for both? Actually, there are only a few particular cases where it makes sense to use the same Form object for both creation and edition in real world programs.

On the other hand, if you don’t want to duplicate some validation logic that is common to both creation and edition you can reuse a mapping fragment in your two Form objects:

val commonMapping = "common" -> tuple(
    "foo" -> number,
    "bar" -> nonEmptyText
)
val creationForm = Form(tuple(
    commonMapping,
    "baz" -> date
) verifying (/* creation specific constraint */))
val editionForm = Form(tuple(
    commonMapping,
    "bah" -> boolean
))


回答2:

I'm doing this workaround in my controllers as i don't know a better solution:

As you can imagine, the isNew value checks your creation case, in my case weather a seq - or 0 in case of creation - is passed via the url

The method userExists(userName: String): Boolean does the check for uniquness.

val boundForm = userForm.bindFromRequest()

if(!boundForm.hasErrors) {
  val user = boundForm.get // save as form has no errors
  if(isNew && userExists(user.getUsername)) {
    boundForm = boundForm.copy(value = None, errors = Seq(FormError("", "user exists, choose another name")))
  }
}

boundForm.fold(...,...)