对用户名的不同模型验证Scala中播放! 在2形式的映射创建和更新(Different mode

2019-09-02 01:18发布

我有用户映射如下(还有其他一些太)

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" -> 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的握在编辑验证。 我必须处理的更新操作方法的编辑呢?

如果我必须这样做,在更新的操作方法示例代码段,因为我也困惑如何操作方法添加的错误信息将是巨大的。

将是真正伟大的,如果有人提供输入这是如何实现的。

我使用Scala的跟玩游戏! 2。

谢谢。

Answer 1:

为了验证了的独特userNamecompany ,我相信问题是,在编辑User ,验证功能查找用户名/公司在数据库,因为它是你事先插入的记录。 所以,你需要检查用户名/公司存在,如果它确实存在,检查行的id是用户的ID。 如果它们是相同的,因为它只有找到你正在更新的记录返回true。

随着的ID User ,最好在处理这种Action ,并因安全隐患而不是形式的结合。 例如,如果ID设置和形式提交,它会很容易有人ID输入的值更改为另一个用户的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")
       }
    )
  }
}


文章来源: Different model validation on User Name in Scala Play! 2 form mapping in create and update