1

私たちの Play アプリケーションはデータ アクセス レイヤーとして Slick を使用します。Requestこれは、アプリのほぼすべてのアクションで、現在のデータベースと Slick のデータベースの両方をSession暗黙的にスコープで使用できるようにする必要があることを意味します。

これを行うためのカスタムを書きたいActionので、これを行うには 1 行しか必要ありません。私がやりたいのは、次のようなものを書くことができるような方法でそれを書くことです:

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

しかし、これは有効な構文ではありません。アクション本体でタプルを暗黙的にアンパックできないため、タプルの使用は機能しません。複数の暗黙的な引数を本体に渡すカスタム アクションを作成することは可能ですか? どうすればいいですか?

4

2 に答える 2

4

そのような 2 つの変数を暗示することはできません。

ただし、カスタム アクションは (リクエストとセッションをカプセル化するオブジェクト) を返すことWrappedRequestができ、このラップされたリクエストとセッションの間の暗黙的な変換を定義できます。

このクラスから派生したこの例を試してください。

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)
  }
}
于 2013-08-02T09:40:36.030 に答える
2

@senia は正しかったです。これを行うにはカリー化を使用する必要があります。これは実際にはPlay ドキュメントで対処されていますが、私が見逃した最近の追加です。

これを探している人のための今後の参考のために、私のカスタム アクションは次のようになります。

def DBAction(action: Request[AnyContent] => Session => Result) = {
  Action { request =>
    database.withSession { session =>
       action(request)(session)
    }
  }
}

次に、次の方法で使用できます。

def someAction = DBAction { implicit request => implicit session => /* body */ }
于 2013-08-02T09:40:20.260 に答える