Play Framework – Scala TodoList
I’ve just finished going through the Scala TodoList sample application in the Play Framework:
http://www.playframework.com/documentation/2.1.0/ScalaTodoList
It’s not exactly the most straightforward written tutorial I’ve come across from a framework so I thought I’d post the full sources here along with an archive of everything:
for people to refer to if they get stuck.
One other thing, it doesn’t tell you to enable database evolutions by default in the application.conf file so make sure you do, it’s not a showstopper by any means, but it’s handy to know.
The application consists of the following sources:
* app/controllers/Application.scala – Main Controller
* app/models/Task.scala – Task Companion Object
* app/views/index.scala.html – Index Template
* conf/application.conf – Configuration
* conf/routes – Routes
* conf/evolutions/default/1.sql – Database Evolution/Migration
Application.scala
| Scala | | copy | | ? |
package controllers |
import play.api._ |
import play.api.mvc._ |
import play.api.data._ |
import play.api.data.Forms._ |
import models.Task |
// Controller |
object Application extends Controller { |
val taskForm = Form( |
"label" -> nonEmptyText |
) |
def index = Action { |
Redirect(routes.Application.tasks) |
} |
def newTask = Action { implicit request => |
taskForm.bindFromRequest.fold( |
errors => BadRequest(views.html.index(Task.all(), errors)), |
label => { |
Task.create(label) |
Redirect(routes.Application.tasks) |
} |
) |
} |
def tasks = Action { |
Ok(views.html.index(Task.all(), taskForm)) |
} |
def deleteTask(id: Long) = Action { |
Task.delete(id) |
Redirect(routes.Application.tasks) |
} |
} |
Task.scala
| Scala | | copy | | ? |
package models |
import anorm._ |
import anorm.SqlParser._ |
import play.api.db._ |
import play.api.Play.current |
case class Task(id: Long, label: String) |
// Task companion object |
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() |
} |
} |
def delete(id: Long) { |
DB.withConnection { implicit c => |
SQL("delete from task where id = {id}").on( |
'id -> id |
).executeUpdate() |
} |
} |
} |
index.scala.html
| Scala | | copy | | ? |
@(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)) { |
<input type="submit" value="Delete"> |
} |
</li> |
} |
</ul> |
<h2>Add a new task</h2> |
@form(routes.Application.newTask) { |
@inputText(taskForm("label")) |
<input type="submit" value="Create"> |
} |
} |
conf/routes
| Text | | copy | | ? |
# Routes |
# This file defines all application routes (Higher priority routes first) |
# ~~~~ |
# Home page |
GET / controllers.Application.index |
# Map static resources from the /public folder to the /assets URL path |
GET /assets/*file controllers.Assets.at(path="/public", file) |
# Tasks |
GET /tasks controllers.Application.tasks |
POST /tasks controllers.Application.newTask |
POST /tasks/:id/delete controllers.Application.deleteTask(id: Long) |
application.conf
| Text | | copy | | ? |
... |
db.default.driver=org.h2.Driver |
db.default.url="jdbc:h2:mem:play" |
... |
conf/evolutions/default/1.sql
| SQL | | copy | | ? |
# Tasks schema |
# --- !Ups |
CREATE SEQUENCE task_id_seq; |
CREATE TABLE task ( |
id INTEGER NOT NULL DEFAULT NEXTVAL('task_id_seq'), |
label VARCHAR(255) |
); |
# --- !Downs |
DROP TABLE task; |
DROP SEQUENCE task_id_seq; |
Hope that helps !
