我想仅在行包含有效数据时更新行中的某个列。具体来说:我有一个Event
的表,其中存储了start
,stop
和isActive
标记。
我希望通过将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就足够了?
答案 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
中的单独方法。