wyc
wyc

Reputation: 55283

Play 2 Scala: Adding a description attribute to this model

The following code is from the Play 2 ScalaTodoList tutorial:

models:

case class Task(id: Long, label: String)

object Task {

  val task = {
    get[Long]("id")~
    get[String]("label") map {
      case id~label => Task(id, label)
    }
  } 

  def all(): List[Task] = DB.withConnection { implicit c =>
    SQL("select * from task").as(task *)
  }

  def create(label: String) {
    DB.withConnection { implicit c =>
      SQL("insert into task (label) values ({label})").on(
        'label -> label
      ).executeUpdate()
    }
  }

Now, I'm trying to add a third attribute called Description:

case class Task(id: Long, label: String, description: String)

object Task {

  val task = {
    get[Long]("id")~
    get[String]("label")~
    get[String]("description") map {
      case id~label~description => Task(id, label, description)
    }
  } 

(I'm a Scala beginner, not sure if I did it right)

But I'm stuck in def create method. How to include description to the SQL query?

EDIT:

I'm also unsure of how to include description here:

  def newTask = Action { implicit request =>
    taskForm.bindFromRequest.fold(
      errors => BadRequest(views.html.index(Task.all(), errors)),
      label => {
        Task.create(label)
        Redirect(routes.Application.tasks)
      }
    )

Upvotes: 2

Views: 464

Answers (1)

Julien Lafont
Julien Lafont

Reputation: 7877

Currently, newTask is a Form[String]: a form which encapsulates a single data, a String.

You need to use a more complex Form to handle both label and description. You can define a case class for these 2 values, or simply use Tuple

case class TaskForm(label: String, description: Form)

In both case, you have at least to modification to do :

** Change the form type in the template :

taskForm: Form[String] => taskForm: Form[(String, String)] // with a tuple

or

taskForm: Form[String] => taskForm: Form[TaskForm] // with the case class defined above

** And now, you can retrieve these values in your controller

// with tuple
taskForm.bindFromRequest.fold(
  errors => BadRequest(views.html.index(Task.all(), errors)),
  values => { Task.create(values._1, values._2) .... }

or

// with case class
taskForm.bindFromRequest.fold(
  errors => BadRequest(views.html.index(Task.all(), errors)),
  form => { Task.Create(form.label, form.description) }   

And of course, you must add a second parameter to Create (or pass the caseclass/tuple object)

def create(label: String, description: String) {
   DB.withConnection { implicit c =>
     SQL("insert into task (label, description) values ({label}, {description})").on(
       'label -> label,
       'description -> description
     ).executeUpdate()
   }
 }

FYI, values, form and errors are arbitrary variable name. You can choose what you want.

ps : You need to adapt your Form(...) too

Upvotes: 2

Related Questions