0

我正在使用 TypeSafe 激活器模板作为应用程序的基础(play+reactivemongo+knockoutJS)。

我正在尝试创建一个用户,在此过程中我想验证他们提供的国家/地区是否已经在数据库中。但由于程序的结构,我发现很难进行验证。

代码

Object UserContoller extends Controller {
  case class UserForm(
      firstName: String, 
      midName: Option[String], 
      lastName: String, 
      addr1: String,
      addr2: Option[String],
      addr3: Option[String],
      city: String,
      state: Option[String],
      zip: String, 
      country: String,
      email: String,
      phone: String
      ) {

    def toUser: User = User(
      BSONObjectID.generate, 
      Name(firstName, midName, lastName), 
      Vector(Email(email)), 
      Vector(Phone(phone)), 
      Address(addr1, addr2, addr3, city, state, zip, CountryDao.find(country))
    )
  }

  implicit val userFormFormat = Json.format[UserForm]

  def save = Action(parse.json) { req =>
    Json.fromJson[UserForm](req.body).fold(
      invalid => {
        BadRequest("Bad form").flashing(Flash(Map("errors" -> JsError(invalid).toString)))
      },
      form => Async {
        UserDao.save(form.toUser).map(_ => Created.flashing(Flash(Map("result" -> "success"))))
      }
    )
  }
}

我的问题是折叠:我需要验证数据库中是否存在国家,并且我需要获取创建用户的国家(这是一个异步操作)。

我最好的想法是让 UserForm 实现一些提供“折叠”方法的东西(如 Json...折叠),因此如果找不到该国家/地区,我可以返回无效。如果我知道它存在,那么构建 MongoDB 查询、等待它并在选项上执行 .get 可能会更容易,因为我已经知道它存在。

希望我说清楚了。

有任何想法吗?

[编辑] 接受了以下建议,并进行了一些更改:您给了我方向,但我对其进行了一些修改:我将 UserForm 类更改为将 Country 作为参数而不是 [string] 国家名称。我想我会将列表传递给将呈现给列表的模板,并且所选国家将被 JSON 化并按原样上传(国家有一个 json.format)。

我在 CountryDao 中创建了 exists(c: Country) 方法,它只是对数据库进行查找并返回结果。

然后,我将 saveUser 更改为:

...
      form => Async {
        CountryDao.exists(form.country) match {
          case c if c==true => {
            UserDao.save(form.toUser map {_ => 
              Created.flashing(Flash(Map("result" -> "success")))
            }          
          }
          case c if c==false => {
            Future(BadRequest("Invalid Country").flashing(
              Flash(Map("errors" -> "Invalid Country"))))
          }
        }
      }

它编译。让我们看看它是否也有效:)

无论如何,我认为现在解决了它。谢谢你

4

1 回答 1

1

一种选择是执行以下操作:

def save = Action(parse.json) { req =>
  Json.fromJson[UserForm](req.body).fold(
    invalid => {
      BadRequest("Bad form").flashing(Flash(Map("errors" -> JsError(invalid).toString)))
    },
    form => Async {
      CountryDao.find(form.country).map { c => // assuming find returns an Option
        UserDao.save(form.toUser(c) /* or form.toUser() */).map(
          _ => Created.flashing(Flash(Map("result" -> "success"))))
      }.getOrElse(
          BadRequest("Invalid Country").flashing(
            Flash(Map("errors" -> "Invalid Country")))) // or something else more appropriate
    }
  )
}

如果您不想两次查找国家/地区,您可以修改您的toUser函数以采用国家类型的参数。Country

def toUser (country: Country): User = User(
  BSONObjectID.generate, 
  Name(firstName, midName, lastName), 
  Vector(Email(email)), 
  Vector(Phone(phone)), 
  Address(addr1, addr2, addr3, city, state, zip, country)
)
于 2013-12-05T13:34:37.803 回答