我的用户映射如下(其他人也很少)
val userMapping: Mapping[User] = mapping(
"id" -> ignored(NotAssigned: Pk[Long]),
"title" -> nonEmptyText,
"name" -> nonEmptyText,
"userName" -> nonEmptyText,
"skype" -> nonEmptyText,
"emailId" -> ignored("": String),
"secondaryEmailId" -> ignored("": String),
"password" -> ignored("": String),
"position" -> optional(text),
"active" -> boolean,
"subscribeEmail" -> boolean,
"creationDate" -> optional(date("yyyy-MM-dd")),
"lastUpdatedDate" -> optional(date("yyyy-MM-dd"))
)(User.apply)(User.unapply)
问题是我将userName上的验证应用为
"userName" -> nonEmptyText.verifying("User name is already taken", user => !User.findUserByUserName(user.userName).isDefined)
这对用户创建完全正常,但在编辑表单上,此验证会中断。 我想为创建和更新使用相同的映射。
目前我已经将它从表单字段移动到表单级别,但是直到所有表单级别错误都没有到达,这个验证从未到达并显示。
我的完整表格映射如下(与公司名称相同的问题)。
val registerForm:Form[(User,Company)] = Form(
mapping(
"user" -> userMapping.verifying("User name is already taken", user => !User.findUserByUserName(user.userName).isDefined),
"password" -> passwordMapping,
"company" -> companyMapping.verifying("Company name is already registered", company => !Company.findCompanyByCompanyName(company.name).isDefined),
"emailPair" -> emailPairMapping
){(user,passwords,company,emailPair) => (user.copy(password = passwords._1,emailId = emailPair._1,secondaryEmailId = emailPair._2,active = true),company)} //binding apply
{userCompanyTuple => Some(userCompanyTuple._1, ("",""),userCompanyTuple._2,(userCompanyTuple._1.emailId,userCompanyTuple._1.secondaryEmailId))} //un binding un apply
)
对于编辑案例,我将映射为(验证仍有待应用)
val registerFormEdit:Form[(User,Company)] = Form(
mapping(
"user" -> userMapping,
"company" -> companyMapping,
"emailPair" -> emailPairMapping
){(user,company,emailPair) => (user.copy(emailId = emailPair._1,secondaryEmailId = emailPair._2,active = true),company)} //binding apply
{userCompanyTuple => Some(userCompanyTuple._1,userCompanyTuple._2,(userCompanyTuple._1.emailId,userCompanyTuple._1.secondaryEmailId))} //un binding un apply
)
我看到的另一个挑战是如何在编辑验证中获取id “id”被忽略。我是否必须在更新操作中处理编辑案例 方法
如果我必须在更新操作方法示例代码段中执行此操作 会很好,因为我也很困惑如何添加错误消息 行动方法。
如果有人提供了如何实现这一目标的输入,那将会非常棒。
我在Play中使用Scala! 2。
感谢。
答案 0 :(得分:3)
为了验证userName
和company
的唯一性,我认为问题在于编辑User
时,验证器函数在数据库中找到userName / company,因为它是您事先插入的记录。因此,您需要检查userName / company是否存在以及它是否存在,检查该行的id是否为该用户的id。如果它们相同,则返回true,因为它只找到了您当前正在更新的记录。
使用User
的id,最好在Action
中处理此问题,而不是由于安全隐患而对表单绑定进行处理。
例如,如果在表单中设置并提交了id,则很容易有人将id输入的值更改为另一个User的id以更改其详细信息。这类似于去年GitHub遭到入侵的http://www.infoq.com/news/2012/03/GitHub-Compromised
就粗略的代码片段而言,有以下几点:
def update(userId: Long) = Action { implicit request =>
val user = User.find(userId)
// Some type of authorization
if(!authorize(getCurrentUser(), user) {
BadRequest("access denied")
} else {
UserFormWithMappings.bindFromRequest().fold(
formWithErrors => Ok("form errors"),
updatedUser => {
updatedUser.id = userId
User.update(updatedUser) // insert into db
Ok("User changes saved")
}
)
}
}