USERS
テーブルからIDの昇順に全件取得し、ユーザ一覧画面を表示します。
ビュー
テンプレートはviews
パッケージに作成します。appディレクトリ配下にviews.user
パッケージを作成し、以下の内容でlist.scala.html
を作成します。
@* このテンプレートの引数 *@
@(users: Seq[models.Users])(implicit request: RequestHeader)
@* テンプレートで利用可能なヘルパーをインポート *@
@import helper._
@* main.scala.htmlを呼び出す *@
@main("ユーザ一覧") {
<div>
<a href="@routes.UserController.edit()" class="btn btn-success" role="button">新規作成</a>
</div>
<div class="col-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(CSRF(routes.UserController.remove(user.id))){
<input type="submit" value="削除" class="btn btn-danger btn-sm"/>
}
</td>
</tr>
}
</tbody>
</table>
</div>
}
テンプレート一行目に(implicit request: RequestHeader)
という引数が定義されていますが、これはテンプレート中で使用しているCSRF
というヘルパーを使用するために必要なものです。PlayではデフォルトでCSRF対策のためのフィルタが有効になっており、フォームの送信先を指定する際に@helper.form(CSRF(...))
のように指定するだけで自動的にトークンを使用したCSRF機能を利用することができます(CSRF
ヘルパーを指定しないとフォームの送信時に403エラーになってしまいます)。
POINT
- テンプレートの1行目にはコントローラから受け取る引数を記述します
- テンプレートには
@
でScalaのコードを埋め込むことができます@import
でインポート文を記述することができます。@import helper._
でPlayが提供する標準ヘルパー(フォームなどを出力する関数)をインポートしています- テンプレートには
@*...*@
でコメントを記述することができます- リンクやフォームのURLは、
@routes.・・・
と記述することでルーティングから生成することができます- デフォルトでCSRFフィルタが有効になっているため、フォームの送信先は
CSRF(...)
で囲む必要があります
コントローラ
UserController
のlist
メソッドを以下のように実装します。
def list = Action { implicit request =>
val u = Users.syntax("u")
DB.readOnly { implicit session =>
// ユーザのリストを取得
val users = withSQL {
select.from(Users as u).orderBy(u.id.asc)
}.map(Users(u.resultName)).list.apply()
// 一覧画面を表示
Ok(views.html.user.list(users))
}
}
val u = Users.syntax("u")
はScalikeJDBCのQueryDSL(SQLをタイプセーフに記述するためのDSL)を使用する際にテーブル毎に必要となるものです。クラス内の様々なメソッドで同じものを使用する場合は以下のようにクラスのフィールドとして定義するようにしてもよいでしょう。
class UserController @Inject()(components: MessagesControllerComponents)
extends MessagesAbstractController(components) {
private val u = Users.syntax("u")
...
}
val users = withSQL {
select.from(Users as u).orderBy(u.id.asc)
}.map(Users(u.resultName)).list.apply()
このコードのselect.from(Users as u).orderBy(u.id.asc)
という部分は以下のSQLと同じ意味になります。
SELECT * FROM USERS ORDER BY ID
POINT
- Playでは
Action { ... }
の中に処理を記述します
implicit request
はアクションの処理の中でHTTPリクエストを暗黙的に使用するために必要になる記述ですOk
にviews.html.・・・
と記述することで、表示したいHTMLのテンプレートを指定できます
- 引数にはテンプレートに渡すパラメータを指定します
- ScalikeJDBCでは
DB.readOnly { ... }
で参照専用のセッションを取得することができますwithSQL { ... }
でSQLをタイプセーフに記述するQueryDSLを使用することができます
実行
ここまで実装したらブラウザから http://localhost:9000/user/list にアクセスします(sbt run
を実行していない場合は実行してください)。すると以下のような画面が表示されるはずです。