仅在满足条件时才更新行

时间:2016-07-09 12:25:34

标签: scala playframework slick slick-3.0

我想仅在行包含有效数据时更新行中的某个列。具体来说:我有一个Event的表,其中存储了startstopisActive标记。 我希望通过将Events设置为isActive来激活一些true,但我需要检查开始和结束日期是否有效。 模型:

 case class Event {start:DateTime, stop:DateTime, isActive:Boolean}

我的验证方法签名:

validateEvent(ev: Event): Boolean

我的第一个方法:

def activateEv() = Action.async(parse.json) { request => { ... val ev = db.run(dao.findEvById(poid, uid)) val ret = ev.flatMap { case st: Option[Event] => if (validateEvent(st.get)) { db.run(dao.updateActivity(poid, true).map { case 0 => false case other => true } } else Future(false) } ... } }

我认为不应该解决这个问题的方式。 你能建议吗? 也许只有一个db.run就足够了?

1 个答案:

答案 0 :(得分:2)

这可以使用db.run对象上的组合器(例如flatMap)在单个DBIOAction中实现。假设您的dao方法看起来像这样:

case object dao {
  def findEvById(poid: Int, uid: Int): DBIOAction[Option[Event], NoStream, Effect.Read] = ???

  // In your case `updateActivity` returns an `Int` and you're mapping it to a `Boolean`.
  // That mapping could be placed here, so `updateActivity` would return `Boolean` now.
  def updateActivity(poid: Int, bool: Boolean): DBIOAction[Boolean, NoStream, Effect.Write] = ???
}

这就是我们如何实现您正在寻找的东西:

...
val action = dao.findEvById(poid, uid).flatMap {
  case Some(event) if validateEvent(event) => dao.updateActivity(poid, true)
  case _ => DBIO.successful(false)
}.transactionally

db.run(action)
...

如您所见,我们在这里有一个交易,它会进行选择,然后进行更新(仅当event有效时)。此外,整个select then update操作可能是dao中的单独方法。