Scala Play 2.0(4) MVCのルーティングとコントローラのつづきのつづき

これのハンズオンです。既にPlay2.1(というか2.2.2)なのでmigrationは不要なため2/3から。

というか、ものっそい今更なのだけど、

def sample = Action {

のActionてなんだろとか思ったので調べてみた。ほぼ答えが以下のURLにあった。

PlayframeworkのActionからscala文法を紐解く - Qiita

それによると、Actionがtraitで、コンパニオンオブジェクトを持っている、とのこと。

自分の理解で言ってしまうとtraitは実装再利用のためのモジュール(classのような継承関係をもたない)で、コンパニオンオブジェクトは対象となるtraitへの共通処理を記述するための同名のオブジェクト、とのこと。正直書いてて理解できてないことがまるわかりだけど、とりあえず、今日の所はおいておこう。

で、コンパニオンオブジェクトが継承(traitだから言い方違うのかな?)しているのがActionBuilderでこれにはapplyメソッドが定義されている。これはいくら自分でも知っている省略形での記述が可能。

Action.apply(hoge)

Action(hoge)

で、処理ブロック{}をrubyの如く引数に突っ込むことができ、さらにcallの際に()が省略可能ということで、

def sample = Action {

は、Action.apply({...の省略形であり、{}は引数であることがわかる。
という感じです。

へー

で、ハンズオンにもどると

・デフォルト引数指定

GET     /sample5          controllers.SampleController.sample5(fixedValue="fixed")
GET     /sample6          controllers.SampleController.sample6(defaultValue:Int ?= 1)
GET     /sample7          controllers.SampleController.sample7(optValue:Option[String])

上から、固定値、無指定時、Option使用(SomeとNoneで判別)という感じ。

 ・リバースルーティング

def sample2 = Action {
    Redirect(routes.SampleController.sample1)   
}

 Redirectにパス直でなくroutes...で指定可能という機能。

・session

ここで突然sessionです。このsessionはサーバーサイドでなくてcookieに入れ込むので、クライアント単位(ブラウザ)でしか閲覧できないのでなんともです。

    def setSession = Action { implicit request =>
        Ok("save session.").withSession(
            session + ("date" -> new java.util.Date().toString()))
    }

PlainResultトレイトのwithSessionメソッドを使えばセッションを保存できます。 

個人的には「お、おう」となったのですが、みなさんいかがでしょうか。Okから帰ってきたPlainResultトレイトをメソッドチェーンのようにwithSessionよびだすのはちょっとびっくりです。あとjava.util.Dateの突然感。

まあ、でもこれでcookieに登録されます。ただ、値を直で変更してもハッシュを持ってるようなので値が無いよという振る舞いになりました。さすがだね。

あとは、Java EEでいうところのrequestスコープみたいなFlash scopeというのがありますよと。

flash

何故かメソッド名がflashingです。

    def setFlash = Action {
        Redirect("/readFlash").flashing(
            "msg" -> "save Flash!")
    }

こうするとflashのmapから値がとれるとか。

今日は以上です。お疲れ様でした。(主に自分が)