Play framework 2.0 のためのブログです。
Comments

ActionのFilter処理を実行するためのTips。

ドキュメントだと、ActionsComposition のこと↓
https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition

今回、Filterの処理内容をTraitとして実装する方法としました。
また、DBアクセスにSlickを使用し、FilterからもDBアクセスできるような実装となっております。

AuthTrait (Filter実装部)

package controllers.components.actions

import models.Users
import play.api.db.slick._
import play.api.mvc.{Result, Request, Action}
import play.api.Play.current

import scala.concurrent.Future

/**
 * Created by yusuke on 2015/01/23.
 */
trait AuthTrait {

  case class Auth[A](action: Action[A]) extends Action[A] {
    def apply(request: Request[A]): Future[Result] = {
      DB.withSession {implicit session =>

        // DB.withSession 内 であれば、Slick経由でDBアクセス可能
        // ここでFilter処理を記載する
        // println(Users.findById(1));

      }

      action(request)
    }
    lazy val parser = action.parser
  }
}


Application (Controller)
package controllers

import controllers.components.actions.AuthTrait
import models.Users
import play.api.mvc._
import play.api.db.slick._
import play.api.Play.current

object Application extends Controller with AuthTrait{

  // 通常アクション
  def index = Action{
    Ok(views.html.index("Your new application is ready."))
  }

  // Authフィルターを使用 (中身はAuthTraitに実装)
  def test = Auth {
    // アクションでDBアクセスする場合はDBAction, しない場合はActionでもOK
    DBAction { implicit rc =>
      Ok(Users.findById(1).toString)
    }
  }

}

複数のFilterをかけたい場合は、同様の形でTraitを定義し、ActionにWrapする形で重ねがけすればOK。重ねる順番で、外側から順番にFilter処理が走ります。
以下の例だと、Filter1実行 → Filter2実行 → DBAction実行
def hoge = Filter1{
  Filter2{
    DBAction{
    }
  }
}
以上です。


 --------------以下追記---------------
ちなみに、POSTデータを取得するには、以下のようにする

① クラスを定義してバインドするパターン

trait AuthTrait {

  // フォームに対応するエンティティを定義
  case class AuthEntity(uid: String, name: String)
  val auth_form = Form(mapping("uid" -> text, "name" -> text)(AuthEntity.apply)(AuthEntity.unapply))

  case class Auth[A](action: Action[A]) extends Action[A] {
    def apply(request: Request[A]): Future[Result] = {
      DB.withSession {implicit session =>

        // リクエストをフォームにバインドして、値を取り出す
        println(auth_form.bindFromRequest()(request).get.name)
      
      }
      action(request)
    }
    lazy val parser = action.parser
  }
}
② バインドせずに、取り出すパターン
val postData: Map[String, Seq[String]] = request.body.asInstanceOf[AnyContentAsFormUrlEncoded].data
println(postData.get("uid").get(0))






Categories: , ,

Leave a Reply