Azuken
Azuken

Reputation: 487

How to use scala case to have multiple parameters?

I've just discovered last week Scala language, with the Play 2 Framework, and I'm a little confused..

I try to make a simple form with an username and a password with this tutorial :

http://www.jamesward.com/2012/02/21/play-framework-2-with-scala-anorm-json-coffeescript-jquery-heroku

but in the controller I have a function who doesn't work :

def addUser() = Action { implicit request =>
  userForm.bindFromRequest.fold(
    errors => BadRequest,
    {
      case (username) =>
        User.create(User(NotAssigned, username, password))
        Redirect(routes.Application.index())
    }
  )
}

It returns : not found: value password

And if i put password in the case, it does'nt wook too..

Any idea ?

Application.scala :

package controllers

import play.api._
import play.api.mvc._
import play.api.data.Form
import play.api.data.Forms.{single, nonEmptyText}
import play.api.mvc.{Action, Controller}
import anorm.NotAssigned

import models.User

object Application extends Controller {

  val userForm = Form {
    tuple(
      "username" -> nonEmptyText,
      "password" -> nonEmptyText
    )
  }

  def index = Action {
    Ok(views.html.index(userForm))
  } 

  def addUser() = Action { implicit request =>
    userForm.bindFromRequest.fold(
      errors => BadRequest,
      {
        case (username, password) =>
          User.create(User(NotAssigned, username, password))
          Redirect(routes.Application.index())
      }
    )
  }
}

User.scala :

package models

import play.api.db._
import play.api.Play.current

import anorm._
import anorm.SqlParser._

case class User(id: Pk[Long], username: String, password: String)

object User {

  val simple = {
    get[Pk[Long]]("id") ~
    get[String]("username") ~
    get[String]("password") map { 
      case username~password => User(id, username)
      case id~username => User(id, username)
    }
  }

  def findAll(): Seq[User] = {
    DB.withConnection { implicit connection =>
      SQL("SELECT * FROM user").as(User.simple *)
    }
  }

  def create(user: User): Unit = {
    DB.withConnection { implicit connection =>
      SQL("INSERT INTO user(username, password) VALUES ({username}, {password})").on(
        'username -> user.username ,
        'password -> user.password
      ).executeUpdate()
    }
  }
}

Upvotes: 1

Views: 1336

Answers (2)

Mikesname
Mikesname

Reputation: 8901

The form you're binding should contain all the values you want to extract, i.e:

import play.api.data.Form
import play.api.data.Forms.{tuple,nonEmptyText}

val userForm = Form(
  tuple(
    "username" -> nonEmptyText, 
    "password" -> nonEmptyText
  )
)

def addUser() = Action { implicit request =>
  userForm.bindFromRequest.fold(
    errors => BadRequest,
    {
      case (username, password) => {
        User.create(User(NotAssigned, username, password))
        Redirect(routes.Application.index())
      }
    }
  )
}

In James's example the form contains just a single field, which will extract to a single value (in your case, username.) Using the "tuple" form mapping will allow you to get more values out.

Upvotes: 2

Mike G.
Mike G.

Reputation: 690

The second argument of fold() function is another function, which takes an object of Form class you're trying to bind to. In your case it would be an "userForm" object:

def addUser() = Action { implicit request =>
  userForm.bindFromRequest.fold(
    errors => BadRequest,
    okForm => { 
      // whatever you want
    }
  )
}

We don't know the type of your form. So difficult to say more. But, as for me, using "case" here is not a good idea.

Upvotes: 0

Related Questions