Команда компиляции активатора Play Scala показывает, что значение userid не является членом play.api.data.Form[models.Changepas Sword]

Я новичок в игре framework (Scala). В моем проекте мне нужно обновить новый Password, для этого мне нужно получить user id, который является Primary key для этого user table. На основе этого уникального значения user id я обновлю Password.

Что мне нужно

нужно получить значение user id таблицы user и передать это значение в контроллер Action

Что я пробовал

контроллеры/users.scala

 import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import views._
import models._


  val changepasswordForm = Form(
          mapping(
            "userid" -> ignored(None:Option[Int]),
              "password" -> tuple(
            "main" -> text,
            "confirm" -> text
          ).verifying(
            // Add an additional constraint: both passwords must match
            "Passwords don't match", passwords => passwords._1 == passwords._2
          ) 
          )(models.Changepassword.apply)(models.Changepassword.unapply)
          )

 def changePassword =   Action {
     Ok(html.changePassword(changepasswordForm))
   }



def updatePassword(userid: Int) = Action { implicit request =>
    changepasswordForm.bindFromRequest.fold(
      formWithErrors => BadRequest(html.changePassword(formWithErrors)),
      user => {
        Changepassword.update(userid, user)
    Ok("password Updated")
      }
    )
  }

модели/User.scala

case class Changepassword(
     userid: Option[Int] = None,
     password:(String,String)
    )
object Changepassword{

    val simple = {
    get[Option[Int]]("user.USER_ID") ~
    get[String]("user.PASSWORD") map {
      case userid~password => Changepassword(userid, (password,password))
    }
  }
     def update(userid: Int,changepassword:Changepassword) = {
    DB.withConnection { implicit connection =>
      SQL("update  user set PASSWORD = {changepassword} where USER_ID = {userid}").
      on('userid -> userid,
          'changepassword -> changepassword.password._1)
      .executeUpdate()
    }
  }
}

views/changePassword.scala.html

@(userForm: Form[Changepassword])

@import helper._

@implicitFieldConstructor = @{ FieldConstructor(twitterBootstrapInput.f) } 

@main("") {

    <h1>Change Password</h1>

    @form(routes.Users.updatePassword(userForm.userid.get)) {

        <fieldset>


            @inputPassword(userForm("password.main"), '_label -> "New Password", '_help -> "",'placeholder -> "New Password")
             @inputPassword(userForm("password.confirm"), '_label -> "Confirm Password", '_help -> "",'placeholder -> "Repeat Password")

        </fieldset>

        <div class="actions">
            <input type="submit" value="Change password" class="btn primary"> or
            <a href="@routes.Application.index()" class="btn">Cancel</a> 
        </div>

    }

}

Если я запускаю команду activator compile, она показывает исключение ниже

D:\Jamal\test>activator compile
[info] Loading project definition from D:\Jamal\test\p
roject
[info] Set current project to scala-crud (in build file:/D:\Jamal\test/)
[info] Compiling 1 Scala source to D:\Jamal\test\targe
t\scala-2.11\classes...
[error] D:\Jamal\test\app\views\changePassword.sc
ala.html:11: value userid is not a member of play.api.data.Form[models.Changepas
sword]
[error]     @form(routes.Users.updatePassword(userForm.userid.get)) {
[error]                                                          ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 13 s, completed Jun 11, 2015 3:52:19 PM

D:\Jamal\test>



Ответы (1)


Вы не можете использовать значение формы в качестве параметра для маршрута:

@form(routes.Users.updatePassword(userForm.userid.get))

Идентификатор пользователя зависит от формы и поэтому может измениться. В любом случае вы получите доступ к идентификатору пользователя формы, используя userForm("userid"), а не userForm.userid (хотя это может быть не то, что вам нужно/нужно).

Лучшим подходом к вашей проблеме было бы передать второй параметр следующим образом:

контроллеры/пользователи.scala

 def changePassword =   Action {
     val userId = ... get the current id ...
     Ok(html.changePassword(changepasswordForm,userId))
   }

просмотры/changePassword.scala.html

@(userForm: Form[Changepassword], userId:Int)
...
...
  @form(routes.Users.updatePassword(userId)) {
   ...
   ...
  }
...

Таким образом, вы гарантируете, что идентификатор пользователя известен при отображении страницы и что «злой» пользователь не может изменить пароли других пользователей, манипулируя идентификатором пользователя.

person Peanut    schedule 15.06.2015
comment
Я проверю и дам вам знать. - person Jamal; 15.06.2015
comment
Я добавил вот так @form(routes.Users.updatePassword(userForm("userid"))) { }, но он показывает type mismatch; found : play.api.data.Field required: Int - person Jamal; 15.06.2015
comment
это потому, что форма содержит не значения, а поля, в том числе множество вспомогательных функций для отображения полей ввода и т. д. Пробовали ли вы передать его в качестве второго параметра, как было предложено? - person Peanut; 15.06.2015
comment
Нет, я знаю второй вариант, так как уже использовал его в своем проекте. Он будет работать. Но мне нужно передать значения из Form, возможно это или нет? - person Jamal; 15.06.2015
comment
Хорошо. Я изменил свой ответ. Вам не нужно передавать идентификатор пользователя в качестве параметра... вы можете просто получить доступ к значению из формы. - person Peanut; 16.06.2015
comment
ваш ответ правильный. У меня есть некоторые сомнения, должны ли мы передать form значение из формы в Action, а затем обновить пароль, как я пробовал routes.Users.updatePassword(userForm.userid.get) и что вы предложили routes.Users.updatePassword(userForm("userid")) - person Jamal; 16.06.2015
comment
Из вашего предыдущего Answer второй подход был правильным. Поскольку этот changePassword.scala.html является пустой формой, изначально он не содержит никаких значений. Поэтому нужно получить USER_ID из DB, а затем обновить пароль на основе возвращенного USER_ID. Так что отмените свое текущее редактирование, я приму ваш ответ. - person Jamal; 16.06.2015
comment
В порядке. Я откатил его обратно. - person Peanut; 16.06.2015