我正在使用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 ... fold),所以如果找不到国家,我可以返回无效。如果我知道它存在,可能更容易构建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"))))
}
}
}
并编译。让我们看看它是否也有效:)
无论如何,我认为现在解决了这个问题。谢谢mantithetical
答案 0 :(得分: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)
)