2013-08-02 86 views
1

我們的Play應用程序使用Slick作爲數據訪問層。這意味着,在我們的應用程序的幾乎每個動作中,我們都需要在作用域上隱式提供當前的Request和Slick的數據庫Session具有多個隱式參數的自定義操作

我想寫一個自定義Action做到這一點,所以我們只需要一條線就可以做到這一點。我想要做的是寫這樣一種方式,我可以寫這樣的一種方式:

def someAction = DBAction { implicit request, session => 
    // body with implicit request and session on scope 

但這是不合法的語法。使用元組不起作用,因爲它不能隱式地將元組解包到操作主體中。是否可以創建一個將多個隱式參數傳遞給body的自定義動作?我該怎麼做呢?

+1

可能重複【如何做兩個函數的參數爲​​隱式(http://stackoverflow.com/questions/17296436/how-to-make-two-function-parameters-as-implicit) – senia

+0

有有兩種方法可以實現這一點:一個curryed動作('Request [AnyContent] => Session => Result' - >請參閱下面的@DCKing答案)或WrappedRequest(請參閱我的答案)。 –

回答

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) 
    } 
} 
+0

很棒的建議!我更喜歡咖喱的解決方案,因爲代碼更簡單,不需要隱式轉換魔術:) – DCKing

+0

我喜歡這個版本,因爲它避免了多個'w => x => y => z'。但是,您的解決方案對於「2級」操作非常有用! –

2

@senia是對的,咖喱需要用來做到這一點。這實際上是在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 */ } 
相關問題