Play framework 2.3 for Scala で、フォームを使ってみる
Play framework 2.3 for Scalaで、フォームからDBへ保存するところをつくってみました。そのおぼえがき。
View…フォームの見え方
Controller…フォームの定義、フォーム表示・受け取り(+DBへの橋渡し)
って感じかな。Controllerがモリモリになってしまいそうだけど、まずは簡単に。
Controller:フォームの定義
先にControllerから。フォームを定義します。
import play.api.data._ import play.api.data.Forms._ case class Book (title : String, price : Int) // ケースクラスを定義する object XXX { val bookForm = Form( // フォームの「型」定義 "title" -> text, "price" -> number(min = 0, max = 1000000) ) (Book.apply) (Book.unapply) }
ケースクラスとフォームの型が別々のファイルにあっても大丈夫。DBアクセスのため、Model側で定義したケースクラスでも問題なし。ネストしたケースクラスでもいけるよう。
View側のフォームから送られてくる値の「制約」を、Form( 〜 )の中に書きます。今はtext(scala.String)と、number (scala.Int)しか定義してませんが、いろいろ制約は書けるみたい。リストも送れる! 以下の公式ドキュメントの"Defining constraints on the form"のあたり参照。
Scala Forms - 2.3.x
Form( 〜 )のあとのケースクラスのapply、unapplyでケースクラスに変換しているけれど、これをTuppleやMapに変換しても使える。便利。
参考サイト
【#Play】Play Framework 2.3 (Scala) を使った Web システム開発入門 #Play_ja #Scala #rpscala - Qiita
Controller:フォームの表示・受け取り(+DBへの橋渡し)
先に定義したフォームの表示・受け取りをするアクションを定義します。
import play.api.mvc._ import play.api.data._ import play.api.data.Forms._ // // 上で定義したケースクラス case class Book...(importでも可) object XXXController extends Controller { // // 上で定義したフォーム val bookForm...(を使えるようにしておく) // 表示用 def showBookForm = Action { implicit request => Ok(views.html.register(bookForm)) } // 登録用 def register = Action { implicit request => bookForm.bindFromRequest.fold ( errors => BadRequest(views.html.error("フォームの入力エラー時の表示")), book => { // 成功時の処理をここに書く、以下は例 Ok(views.html.result(book.title, book.price) } ) } }
処理の中に、ModelのDAOとかを使いたい場合は、ActionではなくてDBActionにする。DBActionは、play.api.db.slick._にあるので、importする必要がある。
DBとのつなぎは以下のサイトが詳しかったので、そちら参照。
【#Play】Play Framework 2.3 (Scala) を使った Web システム開発入門 #Play_ja #Scala #rpscala - Qiita
routesに定義
conf/routes ファイルに、アクセスしたいControllerの定義をかいておく。
# Login GET /register controllers.XXXController.showBookForm() POST /register controllers.XXXController.register()
View:フォームの見え方
表示用のテンプレートを定義。
Controllerで指定したviews.html.xxxというのは、package viewsの中の、xxx.scala.htmlに該当する。
公式ドキュメント:Scala Templates - 2.3.x、Scala Forms - 2.3.xのShowing forms in a view templateの項あたり
views/register.scala.html
@(bookForm: Form[controllers.Book]) @import helper._ <!-- HTMLヘッダー、レイアウトを普通に書ける --> <div> @form(controllers.routes.XXXController.register()) { <fieldset> @inputText(bookForm("title"), '_label -> "タイトル", 'size -> 40) @inputText(bookForm("price"), '_label -> "値段", 'size -> 40) </fieldset> <div class="actions"> <input type="submit"> </div> } </div>
公式ドキュメントScala Forms - 2.3.xにもある通り、@inputTextの部分はinputフィールドのtypeに合わせて様々に用意されている。
views/result.scala.html
@(title: String, price: String) <!-- HTMLヘッダー、レイアウトを普通に書ける --> <table> <tr> <th>タイトル</th> <th>値段</th> <td>@title</td> <td>@price</td> </tr> </table>
公式ドキュメントScala Templates - 2.3.xの通り、Listを受け取ってループで回したりなど、直感的に書ける。便利。
これで、一応使ってみれるフォームはできる。
Viewがかなり書きやすい印象はある。
参考サイト