PlayFramework:在创建之前检查记录的存在

时间:2014-09-08 12:17:30

标签: scala playframework playframework-2.0

我想在play框架应用程序中创建一个注册Action。问题是如何实现对现有电子邮件的检查?

object AccountController extends Controller {

  case class AccountInfo(email: String, password: String)

  val accountInfoForm = Form(
    mapping(
      "email" -> email,
      "password" -> nonEmptyText
    )(AccountInfo.apply)(AccountInfo.unapply)
  )

  def createAccount = Action {
    implicit request => {
      accountInfoForm.bindFromRequest fold (
      formWithErrors => {
        Logger.info("Validation errors")
        BadRequest(accountInfoForm.errorsAsJson)
      },
      accountInfo => {
        AccountService.findByEmail(accountInfo.email) map {
          case accountOpt: Option[Account] => accountOpt match {
            case Some(acc) => {
              Logger.info("Email is already in use")
              BadRequest(Json.toJson(Json.obj("message" -> "Email is already in use")))
            }
            case None => {
              Logger.info("Created account")
              val account = Account.createAccount(accountInfo)
              val accountToSave = account copy (password=Account.encryptPassword(accountInfo.password))
              Created(Json.toJson(AccountService.add(accountToSave)))
            }
          }
          case _ => {
            Logger.info("DB connection error")
            InternalServerError(Json.toJson(Json.obj("message" -> "DB connection error")))
          }
        }
        Ok("Ok")
      })
    }
  }

}

AccountService.findByEmail - 返回Future[Option[Account]]

不幸的是我的解决方案总是返回'Ok'

1 个答案:

答案 0 :(得分:2)

由于findByEmail返回Future,您应该使用Action.async代替map。这是因为当您Future[Option[Account]] Future[Result]时,您将其映射到Result而不是Future.successful。请注意我必须使用formWithErrorsResult来保持返回类型相同。

返回简单的Action时使用Future[Result]。返回Action.async时,请使用def createAccount = Action.async { implicit request => { accountInfoForm.bindFromRequest fold ( formWithErrors => { Logger.info("Validation errors") Future.successful(BadRequest(accountInfoForm.errorsAsJson)) }, accountInfo => { AccountService.findByEmail(accountInfo.email) map { case accountOpt: Option[Account] => accountOpt match { case Some(acc) => { Logger.info("Email is already in use") BadRequest(Json.toJson(Json.obj("message" -> "Email is already in use"))) } case None => { Logger.info("Created account") val account = Account.createAccount(accountInfo) val accountToSave = account copy (password=Account.encryptPassword(accountInfo.password)) Created(Json.toJson(AccountService.add(accountToSave))) } } case _ => { Logger.info("DB connection error") InternalServerError(Json.toJson(Json.obj("message" -> "DB connection error"))) } } }) } }

{{1}}