Фреймворк ScalaQuery и Play: лучшие методы обработки неназначенных первичных ключей (AutoInc)

Я использую Play 2.0.2 со ScalaQuery 0.9.5.

У меня есть следующий простой код модели:

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

object Task extends Table[(Long, String)]("task") {

lazy val database = Database.forDataSource(DB.getDataSource())

def id = column[Long]("id", O PrimaryKey, O AutoInc)
def name = column[String]("name", O NotNull)

def create(task: Task) = database.withSession {
  implicit db: Session => {
    Task.name insert(task.name)
  }
}

И следующий код для обработки отправки формы:

val taskForm: Form[Task] = Form(
  mapping(
    "name" -> nonEmptyText
  ) {
    (name) => Task(-1L, name)
  } {
    task => Some(task.name)
  }
)

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

Несколько вопросов:

1) Есть ли лучший способ обработки временных значений первичного ключа, чем передача константы? Что-то похожее на NotAssigned от Anorm?

2) Не лучше ли добавить «id» -> ignored(-1L) в сопоставление формы и использовать функции извлечения задачи?

3) Должен ли класс case быть определен без поля id?


person avanwyk    schedule 29.07.2012    source источник


Ответы (1)


Если у Task есть идентификатор, вы не должны использовать этот класс для представления значения, у которого нет идентификатора (пока). В любом случае, обычно созданный объект содержит данные, отличные от тех, которые были заполнены в форме (например, дату создания и т. д.), поэтому обычно не имеет смысла использовать один и тот же класс для представления значений, необходимых для создать объект и сам созданный объект.

Таким образом, вы можете определить другой класс case, например. TaskForm (который может в конечном итоге наследоваться от общей базы Task), или, в вашем случае, просто используйте форму, дающую значение String:

// Task
case class Task(id: Long, name: String)

object Task extends Table[(Long, String)]("task") {
  lazy val database = Database.forDataSource(DB.getDataSource())

  def id = column[Long]("id", O PrimaryKey, O AutoInc)
  def name = column[String]("name", O NotNull)

  def create(name: String) = database.withSession { implicit db: Session =>
    Task.name insert(name)
  }
}


// Application
object Application extends Controller {
  val taskForm = Form("name" -> nonEmptyText)
  def newTask = Action { implicit request =>
    taskForm.bindFromRequest.fold(
      errors => BadRequest(views.html.index(Task.all, errors)),
      name => {
        Task.create(name)
        Redirect(routes.Application.tasks())
      }
    )
  }
}
person Julien Richard-Foy    schedule 29.07.2012