USERSテーブルからIDの昇順に全件取得し、ユーザ一覧画面を表示します。

ビュー

テンプレートはviewsパッケージに作成します。appディレクトリ配下にviews.userパッケージを作成し、以下の内容でlist.scala.htmlを作成します。

@* このテンプレートの引数 *@
@(users: Seq[models.Tables.UsersRow])(implicit request: Request[Any])

@* テンプレートで利用可能なヘルパーをインポート *@
@import helper._

@* main.scala.htmlを呼び出す *@
@main("ユーザ一覧") {

<div>
  <a href="@routes.UserController.edit()" class="btn btn-success" role="button">新規作成</a>
</div>

<div class="col-xs-6">
  <table class="table table-hover">
    <thead>
      <tr>
        <th>ID</th>
        <th>名前</th>
        <th>&nbsp;</th>
      </tr>
    </thead>
    <tbody>
    @* ユーザの一覧をループで出力 *@
    @users.map { user =>
      <tr>
        <td>@user.id</td>
        <td><a href="@routes.UserController.edit(Some(user.id))">@user.name</a></td>
        <td>@helper.form(CSRF(routes.UserController.remove(user.id))){
          <input type="submit" value="削除" class="btn btn-danger btn-xs"/>
        }
        </td>
      </tr>
    }
    </tbody>
  </table>
</div>

}

テンプレート一行目に(implicit request: Request[Any])という引数が定義されていますが、これはテンプレート中で使用しているCSRFというヘルパーを使用するために必要なものです。PlayではデフォルトでCSRF対策のためのフィルタが有効になっており、フォームの送信先を指定する際に@helper.form(CSRF(...))のように指定するだけで自動的にトークンを使用したCSRF機能を利用することができます(CSRFヘルパーを指定しないとフォームの送信時に403エラーになってしまいます)。

POINT

  • テンプレートの1行目にはコントローラから受け取る引数を記述します
  • テンプレートには@でScalaのコードを埋め込むことができます
  • @importでインポート文を記述することができます。@import helper._でPlayが提供する標準ヘルパー(フォームなどを出力する関数)をインポートしています
  • テンプレートには@*...*@でコメントを記述することができます
  • リンクやフォームのURLは、@routes.・・・と記述することでルーティングから生成することができます
  • デフォルトでCSRFフィルタが有効になっているため、フォームの送信先はCSRF(...)で囲む必要があります

コントローラ

UserControllerlistメソッドを以下のように実装します。

def list = Action.async { implicit rs =>
  // IDの昇順にすべてのユーザ情報を取得
  db.run(Users.sortBy(t => t.id).result).map { users =>
    // 一覧画面を表示
    Ok(views.html.user.list(users))
  }
}

Action.asyncはアクションの処理結果をFutureで非同期に返却します。Slick 3.0ではSQLの実行処理をFutureで返すことができるため、これを利用してPlayのアクションもFutureでレスポンスを返すようにしています。

上記のコードでは以下の記述でユーザの一覧を取得するDBIOActionを生成しています。

Users.sortBy(t => t.id).result

これは以下のSQLと同じ意味になります。

SELECT * FROM USERS ORDER BY ID

db.runで生成したDBIOActionを実行してデータベースから結果を取得するFutureが返ります。このFutureに対してmapメソッドで、データベースから取得した値をテンプレートに渡してレンダリング結果を返すFutureに変換しています。最終的にこのアクションの戻り値は「DBの検索結果をテンプレートに渡し、そのテンプレートのレンダリング結果を返すFuture」になります。

POINT

  • Playの標準ではAction { ... }の中に処理を記述しますが、レスポンスをFutureで返す場合はAction.async { ... }に処理を記述します
    • implicit rsはアクションの処理の中でHTTPリクエストやDBのセッションを暗黙的に使用するために必要になる記述です
  • Okviews.html.・・・と記述することで、表示したいHTMLのテンプレートを指定できます
    • 引数にはテンプレートに渡すパラメータを指定します
  • Slick 3のクエリはDBIOActionを生成します。DBIOActiondb.runで実行すると検索結果を返すFutureを取得できます

実行

ここまで実装したらブラウザから http://localhost:9000/user/list にアクセスします(sbt runを実行していない場合は実行してください)。すると以下のような画面が表示されるはずです。

ユーザ一覧画面