1

私は次のようにユーザーマッピングを持っています(他にもいくつかあります)

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

  )

私が目にするもう1つの課題は、「id」が無視されるため、編集検証でidを取得する方法です。更新アクション メソッドで編集ケースを処理する必要がありますか?

アクションメソッドにエラーメッセージを追加する方法も混乱しているので、アクションメソッドの更新でそれを行う必要がある場合は、サンプルスニペットが最適です。

誰かがこれを達成する方法を提供してくれれば、本当に素晴らしいことです。

私は Play! で Scala を使っています。2.

ありがとう。

4

1 に答える 1

3

userNameとの一意性を検証するためにcompany、問題は を編集するUserときに、バリデーター関数がデータベースで userName / company を見つけることだと思います。これは、事前に挿入したレコードであるためです。したがって、userName / company が存在するかどうかを確認し、存在する場合は、行の 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")
       }
    )
  }
}
于 2013-06-30T15:18:02.147 に答える