Play2.3-slick2.1s

ユーザ登録・編集画面の実装

リクエストパラメータにIDが指定押されているかどうかに応じて以下の処理を行います。 リクエストパラメータにIDなし ⇒ 新規登録画面を表示します。 リクエストパラメータにIDあり ⇒ USERSテーブルを検索し、該当のユーザ情報を初期表示した編集画面を表示します。 フォーム 画面からの入力値を受け取るためのFormをコントローラに定義します。Formは必ずしもコントローラに定義する必要はないのですが、コントローラでの処理に強く依存するため特に理由がない限りコントローラ内に定義するとよいでしょう。 まず、UserControllerの冒頭に以下のインポート文を追加します。これでFormの定義や基本的なバリデーションができるようになります。 import play.api.data._ import play.api.data.Forms._ 登録・編集画面からの入力値を受け取るためのFormを定義します。 object UserController extends Controller { // フォームの値を格納する case class UserForm(id: Option[Long], name: String, companyId: Option[Int]) // formのデータ⇔ケースクラスの変換を行う val userForm = Form( mapping( "id" -> optional(longNumber), "name" -> nonEmptyText(maxLength = 20), "companyId" -> optional(number) )(UserForm.apply)(UserForm.unapply) ) ... POINT FormはStrutsのアクションフォームのようなものです マッピングに従ってバリデーション(後述)が行われます ビュー 続いてviews.

ルーティングの定義

Bootstrapを使うための準備 play newコマンドで作成されたプロジェクトにはデフォルトのレイアウトテンプレートとしてapp/views/main.scala.htmlが生成されています。ここにBootstrapで使用するCSSとJavaScriptを追加します。 @(title: String)(content: Html) <!DOCTYPE html> <html> <head> <title>@title</title> <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")"> <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")"> <script src="@routes.Assets.at("javascripts/hello.js")" type="text/javascript"></script> @* ↓↓↓↓ここから追加↓↓↓↓ *@ <link rel="stylesheet" media="screen" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css"> <link rel="stylesheet" media="screen" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js" type="text/javascript"></script> @* ↑↑↑↑ここまで追加↑↑↑↑ *@ </head> <body> @content </body> </html> コントローラの雛形を作る controllersパッケージにUserControllerオブジェクトを以下のように作成します。 package controllers import play.api.mvc._ object UserController extends Controller { /** * 一覧表示 */ def list = TODO /** * 登録・編集画面表示 */ def edit(id: Option[Long]) = TODO /** * 登録実行 */ def create = TODO /** * 更新実行 */ def update = TODO /** * 削除実行 */ def remove(id: Long) = TODO } POINT

削除処理の実装

指定したIDのユーザをUSERSテーブルから削除し、一覧画面へリダイレクトします。 コントローラ すでに一覧画面に「削除」ボタンは表示されているので、そこから呼び出されるコントローラのメソッドのみ実装します。 def remove(id: Long) = DBAction.transaction { implicit rs => // ユーザIDを指定して削除 Users.filter(t => t.id === id.bind).delete // 一覧画面へリダイレクト Redirect(routes.UserController.list) } 上記のコードでは以下の記述でユーザ情報の削除を行っています。 Users.filter( t => t.id === id.bind).delete これは以下のSQLと同じ意味になります。 DELETE FROM USERS WHERE ID = ? 実行 一覧画面から「削除」をクリックしてユーザ情報が削除されることを確認してください。

登録・更新処理の実装

入力値のバリデーションを行い、エラーの有無に応じて以下の処理を行います。 エラーあり ⇒ フォームにエラー情報をセットして入力フォームに戻ります。 エラーなし ⇒ DBへの登録・更新処理を行い、一覧画面へリダイレクトします。 コントローラ UserControllerのメソッドのうち、登録処理を行うcreateメソッドと更新処理を行うupdateメソッドを実装します。 入力フォームの値を受け取るには、userForm.bindFromRequestメソッドでリクエストの内容をFormにバインドし、foldメソッドでエラーがあった場合の処理と、OKの場合の処理を記述します。以下はcreateメソッドの実装例です。 def create = DBAction.transaction { implicit rs => // リクエストの内容をバインド userForm.bindFromRequest.fold( // エラーの場合は登録画面に戻す error => BadRequest(views.html.user.edit(error, Companies.sortBy(t => t.id).list)), // OKの場合は登録を行い一覧画面にリダイレクトする form => { // ユーザを登録 val user = UsersRow(0, form.name, form.companyId) Users.insert(user) // 一覧画面にリダイレクト Redirect(routes.UserController.list) } ) } updateメソッドも同じように実装します。 def update = DBAction.