playとSquerylでフォームの内容をDBに反映させるまで

前回はDBの操作をひと通り行ったので、今回は前々回で定義したdb.Postを使ってフォームの内容をDBに反映させます。
前々回の記事
play frameworkでSqueryl Schema及びentity定義するまで - hikonori07’s blog

これから簡易ブログシステムを作成します。
その簡易ブログシステムのページ構成はこのようになっています。
・ブログ一覧
→indexページ

・投稿ページ
→postページ

・記事の更新
→updateページ

今回は上の3つのうちの1つ、postページを作成していきます。

・フォームの内容をDBのpostテーブルに反映させる

なおplay2.3とSquerylを使って作成していきます。

最初にviewの設定

app/views/post.scala.htmlファイル

@(form: play.api.data.Form[db.Post])

//@helper.formでフォームを宣言
@helper.form(action = routes.Application.addPost) {
@helper.inputText(form("title"))
@helper.inputText(form("content"))
<input type="submit"/>

}

helperを使ってHTMLフォームを出力するのは↓のページを参考に
Play2.0(Scala)のForm HelperでHTMLフォームを作る | mwSoft

conf/routesの設定

//フォーム画面
GET      /post                        controllers.Application.post

//フォーム内容を送信したときのアクション先として
POST    /addPost                   controllers.Application.addPost

Getting Started with Play 2, Scala, and Squeryl

フォーム内容のアクション先として指定しているaddPostを作成

app/controllers/Application.scalaファイル

 def addPost = Action { implicit request =>
    val result = postForm.bindFromRequest.fold(
      errors => { BadRequest },
      post => { 
//       inTransaction(AppDB.postTable.insert(new Post(post.title, post.content)))
//上の記述をのせていましたが、下の記述でも大丈夫なようです
        inTransaction(AppDB.postTable.insert(post))
        Redirect(routes.Application.index())
      }
    )
    result
  }

リクエストを受け取り参照する方法や、暗黙的な引数とする方法が↓で説明されています。
https://www.playframework.com/documentation/2.3.x/ScalaActions


bindFromRequestの使い方とimplicitしている理由
→「Controllerロジックの実装」に説明あり
http://www.colibrifw.org/chapter03/section05/databaseapp.html

また今回error時の処理も行う必要があるためbindFromRequest.foldを使用しています。
error時にはBadRequestを投げ、正常時にはinsert文を実行してリダイレクト処理を行っています。
またerrorsやpostは束縛され変数としてその後の処理で参照できるため、分かりやすい変数名をしっかりつけるようにしたほうがいいでしょう。
最初そのことを分からず、errorとsuccessにしていました。。。

フォーム入力画面の作成

indexページにはpostの一覧を表示する予定なので今回は、controllerにpostアクションを追加。
app/controllers/Application.scalaファイル

//フォームの定義
  val postForm = Form(
    mapping(
      "title" -> text,
      "content" -> text
    )(Post.apply)(Post.unapply)
  )

//postFormを渡す
  def post = Action {
    Ok(views.html.post(postForm))
  }


ひと通りできたところで、Loggerでフォームで渡された内容(request.body)を表示
request.bodyにはこんな内容が飛んできていました。

AnyContentAsFormUrlEncoded(Map(title -> ArrayBuffer(hello Rails), content -> ArrayBuffer(play with friends)))


参考ページ
Getting Started with Play 2, Scala, and Squeryl