как применять валидаторы форм на объекте - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть API в Scala.Когда я хочу создать нового пользователя, мне нужны валидаторы в некоторых полях (UserName, FirstName, LastName).Я не могу найти решение применить Форму в моем классе дел Пользователь.Я думал, что с помощью (User.apply) это автоматически переопределит мой User класс, но этого не происходит.

User.scala

 case class User(
              id: Int = 0,
              userName: String,
              firstName: String,
              lastName: String
            )

object User {
  import play.api.libs.json._

  implicit val jsonWrites = Json.writes[User]

  implicit val userReads = Json.reads[User]

  def tupled = (User.apply _).tupled
}

// Form validator for post requests
object UserForm {
  val form: Form[User] = Form(
    mapping(
      "id" -> number,
      "userName" -> text(minLength = 5),
      "firstName" -> text(minLength = 5),
      "lastName" -> nonEmptyText
    )(User.apply)(User.unapply)
  )
}

UsersController.scala

def create = Action(parse.json) { implicit request => {
    val userFromJson = Json.fromJson[User](request.body)
    userFromJson match {
      case JsSuccess(user: User, path: JsPath) => {
        var createdUser = Await.result(usersRepository.create(user), Duration.Inf)
        Ok(Json.toJson(createdUser))
      }
      case error @ JsError(_) => {
        println(error)
        InternalServerError(Json.toJson("Can not create user"))
      }
      }
    }
  }

UsersRepository.scala

    def create(user: User): Future[User] = {
      val insertQuery = dbUsers returning dbUsers.map(_.id) into ((x, id) => x.copy(id = id))
      val query = insertQuery += user
      db.run(query)
    }

(UsersRepository не имеет большого значения в этой проблеме)

Итак, когда я читаю json, я думаю, что нужно применять валидаторы форм

val userFromJson = Json.fromJson[User](request.body)

, но ничего не происходит.Другая проблема, если я отправлю с клиента параметр null, получит ошибку, не сможет прочитать и создать пользователя.

Например:

"firstName": "" - пустое имя пользователя пройдет

"firstName": null - не удастся

Это зависит от того, как настроен User класс в клиенте (Angular), с полем пустым или пустым в конструкторе.Я предпочитаю устанавливать его на нуль, даже если это строка, если это не обязательное поле (лучше значение NULL в базе данных, чем пустая ячейка)

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Найдите решение, моя Форма должна быть частью объекта Пользователь, а не быть другим объектом.

  object User {
  import play.api.libs.json._

  implicit val jsonWrites = Json.writes[User]    
  implicit val userReads = Json.reads[User]

  val form: Form[User] = Form(
    mapping(
      "id" -> number,
      "userName" -> text(minLength = 2),
      "firstName" -> text(minLength = 4),
      "lastName" -> nonEmptyText
    )(User.apply)(User.unapply)
  )

  def tupled = (User.apply _).tupled
}

и метод в Контроллере стал:

def create = Action(parse.json) { implicit request => {
    User.form.bindFromRequest.fold(
      formWithErrors => BadRequest(Json.toJson("Some form fields are not validated.")),
      success => {
        val userFromJson = Json.fromJson[User](request.body)
        userFromJson match {
          case JsSuccess(user: User, path: JsPath) => {
            val createdUser = Await.result(usersRepository.create(user), Duration.Inf)
            Ok(Json.toJson(createdUser))
          }
          case error@JsError(_) => {
            println(error)
            InternalServerError(Json.toJson("Can not create user"))
          }
        }
      }
    )
   }
  }

Iзнаете, мне нужно отформатировать код ... использование IntelliJ очень раздражает после Visual Studio: (

0 голосов
/ 26 сентября 2019

Попробуйте использовать это:

request.body.validate[User]

Еще одна вещь, вы не должны использовать

var createdUser = Await.result(usersRepository.create(user), Duration.Inf)

Так что используйте val'ы над var´s и другую вещь, выне нужно заставлять будущее решать, используйте это так:

val createdUser = usersRepository.create(user)
createdUser.map(Ok(Json.toJson(_)))

И ваши действия должны быть асинхронными.

...