USERSテーブルからIDの昇順に全件取得し、ユーザ一覧画面を表示します。
ビュー
テンプレートはviewsパッケージに作成します。appディレクトリ配下にviews.userパッケージを作成し、以下の内容でlist.scala.htmlを作成します。
@* このテンプレートの引数 *@
@(users: Seq[models.Tables.UsersRow])
@* 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> </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(routes.UserController.remove(user.id)){
<input type="submit" value="削除" class="btn btn-danger btn-xs"/>
}
</td>
</tr>
}
</tbody>
</table>
</div>
}
POINT
- テンプレートの1行目にはコントローラから受け取る引数を記述します
- テンプレートには
@でScalaのコードを埋め込むことができます- テンプレートには
@*...*@でコメントを記述することができます- リンクやフォームのURLは、
@routes.・・・と記述することでルーティングから生成することができます
コントローラ
UserControllerのlistメソッドを以下のように実装します。
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のセッションを暗黙的に使用するために必要になる記述ですOkにviews.html.・・・と記述することで、表示したいHTMLのテンプレートを指定できます
- 引数にはテンプレートに渡すパラメータを指定します
- Slick 3.0のクエリは
DBIOActionを生成します。DBIOActionをdb.runで実行すると検索結果を返すFutureを取得できます
実行
ここまで実装したらブラウザから http://localhost:9000/user/list にアクセスします(activator runを実行していない場合は実行してください)。すると以下のような画面が表示されるはずです。
