我们的Play应用程序使用Slick作为数据访问层。这意味着在我们的应用程序中的几乎每个操作中,我们都需要在范围内隐式提供当前Request
和Slick的数据库Session
。
我想编写一个自定义Action
来执行此操作,因此我们只需要一行来执行此操作。我想要做的是以这样的方式写它,我可以写这样的东西:
def someAction = DBAction { implicit request, session =>
// body with implicit request and session on scope
但这不是有效的语法。使用元组不起作用,因为它无法隐式解压动作体中的元组。是否可以创建一个自定义操作,将多个隐式参数传递给正文?我该怎么做?
答案 0 :(得分:4)
你不能隐含2个这样的变量。
但是您的自定义操作可以返回WrappedRequest
(封装请求和会话的对象),您可以在此包装请求和会话之间定义隐式转换。
尝试此示例,源自此class。
sealed case class DBRequest(session: Session, private val request: Request[AnyContent])
extends WrappedRequest(request)
trait DBController extends Controller {
// Implicit conversion from DBRequest to Session
implicit def session(implicit request: DBRequest) = request.session
def DBAction(action: DBRequest => Result) = Action { request =>
database.withSession { session =>
action(DBRequest(session, request))
}
}
}
object MyController extends Controller with DBController {
def myAction = DBAction { implicit request =>
println(session)
}
}
答案 1 :(得分:2)
@senia是对的,currying需要用来做这件事。这实际上是在Play docs中解决的,但这是我最近错过的一个补充。
为了寻找此人的未来参考,我的自定义操作现在看起来像这样:
def DBAction(action: Request[AnyContent] => Session => Result) = {
Action { request =>
database.withSession { session =>
action(request)(session)
}
}
}
然后我可以通过以下方式使用:
def someAction = DBAction { implicit request => implicit session => /* body */ }