3

我遇到了这样一种情况,即我的数据模型中需要大量数据,但这些数据是在服务器端提供的,并且只显示在 gui 中。在使用 slick 的 play 2 中,我还没有找到这样做的好方法。以跟踪数据的创建和修改(created、lastUpdated)为例:

    case class TrackedData(id:Option[Long],description:String, created:DateTime:new DateTime(),lastUpdated:DateTime=new DateTime())

    object TrackedDatas extends Table[TrackedData]("TrackedData"){
      def id = column[Long]("id",O.primaryKey)
      def description = column[String]("description", O.NotNull)
      def created = column[Timestamp]("created", O.NotNull)
      def lastUpdated = column[Timestamp]("lastUpdated", O.NotNull)
      def * = id.? ~ created ~ lastUpdated <>(TrackedData.apply _, TrackedData.unapply _)
}

在此示例中,“描述”是我希望用户提供的唯一内容,created 和 lastUpdated 将在服务器端提供,但我确实想在 Web 上显示此信息。这样做似乎很笨拙。首先,您必须将 create 和 lastUpdated 映射到可选字段,以便在您不提交它们时表单绑定不会中断,但这意味着您不能使用默认案例类 .apply 和 .unapply 方法,并且必须提供映射以解决此问题控制器然后变为:

object TrackedDataController extends Controller {
val form = Form(
    mapping(
      "id" -> optional(longNumber),
      "created" -> optional(jodaDate("dd.MM.yyyy HH:mm:ss", DateTimeZone.UTC)),
      "lastUpdated" -> optional(jodaDate("dd.MM.yyyy HH:mm:ss", DateTimeZone.UTC)),
      "description" -> text
    )((id, _, _) => TrackedData(id = id))
      ((trackedData:TrackedData) => Some(trackedData.id,Option(trackedData.created),Option(trackedData.lastUpdated)  ,trackedData.descscription))
  )
}

如果这是例外情况也不会太糟糕,但是大多数数据将遵循这种模式(加上 createdBy 和 lastModifiedBy),所有这些都是服务器端必需和提供的,但需要在浏览器端显示。在隐藏字段中发布“只读”数据是解决此问题的唯一方法吗?上面还有一个额外的问题,除非您在更新期间通过检索现有值并将其复制到传入数据中明确保护它,否则您将覆盖任何只读数据:

  update(data:TrackedData){
        val existing:T = this.byId(toSave.id.get).get
        toSave.created = existing.created
        toSave.lastUpdated = new DateTime()
        this.where(_.id===toSave.id).update(toSave)
    }

这些都不是太可怕,只是似乎必须有更好的方法。建议?

4

1 回答 1

0

一种选择是使用play-autosource,它基本上提供具有不同后端(mongo、slick、...)的 CRUD,并通过在 Play 的 json api 上运行来实现。使用转换器,您可以转换和验证您的数据。但是,这是一个实验项目。

作为一个侧节点,我们正在开发一个试图解决这些问题的开源项目。如果您有兴趣,我们将在 3 月中旬的 play 邮件组中宣布它。

于 2014-02-07T19:51:50.393 回答