Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the proper way to generate evolutions and models in Play 2?
    text
    copied!<p>I know evolutions are applied automatically in dev mode. My question is, how do I generate the evolutions? And how do I generate the models that correspond to them? I'm currently faced with a lot of typing to enter a simple model. It isn't DRY and there's lots of boilerplate. This seems counter to the culture of Play.</p> <p>Here is the code I'm faced with typing, what is the better way?:</p> <p>1.sql: # --- First database schema</p> <pre><code># --- !Ups create table task ( id bigint not null primary key, title varchar(255) not null, done boolean, due_date timestamp, assigned_to varchar(255), project bigint not null, folder varchar(255), foreign key(assigned_to) references user(email) on delete set null, foreign key(project) references project(id) on delete cascade ); # --- !Downs drop table if exists task; </code></pre> <p>Task.scala:</p> <pre><code>package models import java.util.{Date} import play.api.db._ import play.api.Play.current import anorm._ import anorm.SqlParser._ case class Task(id: Pk[Long], folder: String, project: Long, title: String, done: Boolean, dueDate: Option[Date], assignedTo: Option[String]) object Task { // -- Parsers /** * Parse a Task from a ResultSet */ val simple = { get[Pk[Long]]("task.id") ~ get[String]("task.folder") ~ get[Long]("task.project") ~ get[String]("task.title") ~ get[Boolean]("task.done") ~ get[Option[Date]]("task.due_date") ~ get[Option[String]]("task.assigned_to") map { case id~folder~project~title~done~dueDate~assignedTo =&gt; Task( id, folder, project, title, done, dueDate, assignedTo ) } } // -- Queries /** * Retrieve a Task from the id. */ def findById(id: Long): Option[Task] = { DB.withConnection { implicit connection =&gt; SQL("select * from task where id = {id}").on( 'id -&gt; id ).as(Task.simple.singleOpt) } } /** * Retrieve todo tasks for the user. */ def findTodoInvolving(user: String): Seq[(Task,Project)] = { DB.withConnection { implicit connection =&gt; SQL( """ select * from task join project_member on project_member.project_id = task.project join project on project.id = project_member.project_id where task.done = false and project_member.user_email = {email} """ ).on( 'email -&gt; user ).as(Task.simple ~ Project.simple map { case task~project =&gt; task -&gt; project } *) } } /** * Find tasks related to a project */ def findByProject(project: Long): Seq[Task] = { DB.withConnection { implicit connection =&gt; SQL( """ select * from task where task.project = {project} """ ).on( 'project -&gt; project ).as(Task.simple *) } } /** * Delete a task */ def delete(id: Long) { DB.withConnection { implicit connection =&gt; SQL("delete from task where id = {id}").on( 'id -&gt; id ).executeUpdate() } } /** * Delete all task in a folder. */ def deleteInFolder(projectId: Long, folder: String) { DB.withConnection { implicit connection =&gt; SQL("delete from task where project = {project} and folder = {folder}").on( 'project -&gt; projectId, 'folder -&gt; folder ).executeUpdate() } } /** * Mark a task as done or not */ def markAsDone(taskId: Long, done: Boolean) { DB.withConnection { implicit connection =&gt; SQL("update task set done = {done} where id = {id}").on( 'id -&gt; taskId, 'done -&gt; done ).executeUpdate() } } /** * Rename a folder. */ def renameFolder(projectId: Long, folder: String, newName: String) { DB.withConnection { implicit connection =&gt; SQL("update task set folder = {newName} where folder = {name} and project = {project}").on( 'project -&gt; projectId, 'name -&gt; folder, 'newName -&gt; newName ).executeUpdate() } } /** * Check if a user is the owner of this task */ def isOwner(task: Long, user: String): Boolean = { DB.withConnection { implicit connection =&gt; SQL( """ select count(task.id) = 1 from task join project on task.project = project.id join project_member on project_member.project_id = project.id where project_member.user_email = {email} and task.id = {task} """ ).on( 'task -&gt; task, 'email -&gt; user ).as(scalar[Boolean].single) } } /** * Create a Task. */ def create(task: Task): Task = { DB.withConnection { implicit connection =&gt; // Get the task id val id: Long = task.id.getOrElse { SQL("select next value for task_seq").as(scalar[Long].single) } SQL( """ insert into task values ( {id}, {title}, {done}, {dueDate}, {assignedTo}, {project}, {folder} ) """ ).on( 'id -&gt; id, 'folder -&gt; task.folder, 'project -&gt; task.project, 'title -&gt; task.title, 'done -&gt; task.done, 'dueDate -&gt; task.dueDate, 'assignedTo -&gt; task.assignedTo ).executeUpdate() task.copy(id = Id(id)) } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload