Playframework(11)Scala Project and First Example

Playframework(11)Scala Project and First Example
Maybe, I will try emacs in the future, but this time, still I will use eclipse.

Project creation
>play new todolist

And this time I choose simple Scala application.

prepare the IDE
>cd todolist
>play eclipsify

Then we can import this project to eclipse.
Enter the play console and start the web container
>play
play>run

Visit http://localhost:9000 to make sure it is working.

Overview
Configuration is almost the same as Java. So there is no comments here.

Development workflow
Change the Application.scala to simple content.

object Application extends Controller{
     def index = Action {
          Ok("Hello Sillycat!")
     }
}

Preparing the application
Did the same things as in Java Project, configure the routes file first.

And make the control TODO first.

def tasks = TODO
def newTask = TODO
def deleteTask(id: Long) = TODO

Prepare the Task model
Firstly create the package models under app.

The create a scala class Task.scala with Scala Wizards ---> Scala Object

The content are as follow, till now, the Scala language looks better than Java.
package models

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

object Task {
 
  def all() : List[Task] = Nil
 
  def create(label: String) {}
 
  def delete(id: Long) {}

}

The application template
Modify the index.scala.html template for task list and form just like in Java project.

The template engine is designed by Scala, it seems working with Scala backend is much better than with Java.
@(tasks: List[Task], taskForm: Form[String])

@import helper._

@main("Todo List") {
<h1]]>@tasks.size task(s)</h1]]>
<ul]]>
@tasks.map { task =>
  <li]]>
@task.label

@form(routes.Application.deleteTask(task.id)){
  <inputtype="submit"value="Delete"]]>
}
  </li]]>
}
</ul]]>

<h2]]>Add a new task</h2]]>

@form(routes.Application.newTask){
  @inputText(taskForm("label"))
  <inputtype="submit"value="Create"]]>
}
 
}

The task form
A Form object encapsulates an HTML Form definition, including validation constraints.

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

val taskForm = Form(
     "label" -> nonEmptyText
)

Rendering the first page
I implement the action tasks like this:
  def tasks = Action {
    Ok(views.html.index(Task.all(), taskForm))
  }

but I got
Error Message:
too many arguments for method apply

Solution:
Right now, it seem right, but eclipse did not aware of that. I have no solution. I already have Scala plugins in my class.

Oops, I find the properties of the project and choose the Scala Compiler and uncheck the [Use Project Settings]

Handling the form submission
Handle and implement the newTask action
  def newTask = Action { implicit request =>
    taskForm.bindFromRequest.fold(
      errors => BadRequest(views.html.index(Task.all(), errors)),
      label => {
        Task.create(label)
        Redirect(routes.Application.tasks)
      })
  }

Persist the tasks in a database
Change the database configuration in conf/application.conf according to the Java Project.
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"

The differences are that we need to create the SQL table for that.
create the file conf/evolutions/default/1.sql
#Tasks schema

# ----!Ups
CREATE SEQUENCE task_id_seq;
CREATETABLE task (
id integerNOTNULLDEFAULT nextval('task_id_seq'),
label varchar(255)
);

# --- !Downs
DROPTABLE task;
DROP SEQUENCE task_id_seq;

After I create the SQLs, I refresh the page. Play tell me we need evolution. I click on Apply this script. It is really magic.

Next step is to implement the SQL queries. Define the using of Anorm first

 
import anorm._
import anorm.SqlParser._

    val task = {

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

import play.api.db._
import play.api.Play.current
  def all() : List[Task] = DB.withConnection { implicit c =>
    SQL("select * from task").as(task *)
  }

Pay attention to the import statements, sometimes, eclipse can not import that for you.
  def create(label: String) {
    DB.withConnection{ implicit c =>
         SQL("insert into task (label) values ( {label} ) ").on(
              'label -> label
         ).executeUpdate()
    }
  }
 
  def delete(id: Long) {
    DB.withConnection { implicit c =>
    SQL("delete from task where id = {id}").on(
    'id -> id
    ).executeUpdate()
    }
  }

Adding the Deleting Tasks
  def deleteTask(id: Long) = Action {
    Task.delete(id)
    Redirect(routes.Application.tasks())
  }

It is there, it is done. Totally speaking, I feel play framework is really great, and it is worthing speed time on Scala. It is really a magic language.

Spring, Java and a lot of related J2EE framework, they are my old lovers now.

References:
http://www.playframework.org/documentation/2.0.4/ScalaTodoList


你可能感兴趣的:(playframework)