連載
» 2013年07月29日 18時00分 公開

Scala+Play 2.0でWebアプリ開発入門(8):Playのグローバルな設定&spec2でBDDなテスト (2/4)

[中村修太,クラスメソッド]

ユーザー登録アプリの修正

 テストを作成する前に、ユーザー登録機能を修正します。モデル・コントローラ・テンプレートを修正し、サービスクラスを新たに追加します。

モデル修正

 Userテーブルに合わせて、モデルオブジェクトを次のように修正します。

//models/models.scala
case class User(id:Option[Long],name:String, 
  email: String,password:String,createDate:Option[Timestamp])

 idとcreateDateはnullの可能性があるので、Option型で宣言します。

サービス作成

 次に、app/servicesディレクトリを作成し、UserService.scalaファイルを作成します。そこに実際データベースにアクセスする、UserServiceオブジェクトを作成します。

package services
import models.User
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
import java.sql.Timestamp
object UserService {
  /** Userテーブルのすべてのカラムを取得 */
  private val * = {
    int("id") ~ str("name") ~ str("email") ~ str("password") ~ date("createDate") map {
      case id ~ name ~ email ~ password ~ createDate =>
        User(Some(id), name, email, password, Some(new Timestamp(createDate.getTime())))
    }
  }
  /** ユーザーのPK検索 */
  def findByPk(id:Long): Option[User] = {
    DB.withConnection { implicit c =>
      SQL("select * from User where id = {id}")
        .on('id -> id)
        .as(*.singleOpt)
    }
  }
  /** ユーザー登録. */
  def entry(name: String, email: String, password: String):Option[Long] = {
    DB.withConnection { implicit c =>
      SQL(
        """ insert into User(name,email,password) values({name},{email},{password}) """)
        .on('name -> name, 'email -> email, 'password -> password).executeInsert()
    }
  }
}

 UserServiceオブジェクトでは2つのメソッドを定義します。findByPk関数はid(プライマリキー)を受け取って対応するUserオブジェクトを返します。entryメソッドではフォームから入力された値を受け取り、新たなユーザーを登録します。

 また、entryが返す値は登録されたユーザーのidの値となっています。

 private変数として「*」が定義されていますが、これはfindByPkのas関数内で使われています。Userテーブルのselect結果をパースし、Userオブジェクトを構築して返すためのパース用関数です。こうやって定義しておけば、他の関数でも使い回せるので便利ですね。

コントローラ修正

 そして、UserControllerの修正を行います。フォームをTuple3で定義し、entrySubmitではUserServiceを呼び出してデータベースに登録しています。

 登録がうまくいったら、findByPkを呼び出してユーザー情報を取得し、結果画面へ渡しています。

package controllers
import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import models._
import services.UserService
object UserController extends Controller {
  val userForm = Form(
    tuple(
      "name" -> nonEmptyText,
      "email" -> email,
      "password" -> nonEmptyText))
  def entryInit = Action { implicit request =>
    val filledForm = userForm.fill("name", "email", "password")
    Ok(views.html.user.entry(flash.get("result").getOrElse(""), filledForm))
  }
  def entrySubmit = Action { implicit request =>
    userForm.bindFromRequest.fold(
      errors => {
        BadRequest(views.html.user.entry("error", errors))
      },
      success => {
        val (name, email, password) = success
        UserService.entry(name,email,password) match {
          case Some(id) => {
            UserService.findByPk(id) match {
              case Some(u) => Ok(views.html.user.entrySubmit(u))
              case None => Redirect("/user/entry").flashing("result" -> "user not found")
            } 
          }
          case None => Redirect("/user/entry").flashing("result" -> "entry failure")
        }     
      })
  }
}

Scalaテンプレート修正

 モデルやコントローラを修正したので、それに付随してScalaテンプレートも修正しなければいけません。views/user/entry.scala.htmlでは、フォームの型や引数、入力項目などを次のように修正しましょう。

@(result:String,userForm: Form[(String,String,String)])
@import helper._
@main("entry user") {
  <h1>Entry user</h1>
  @helper.form(action = routes.UserController.entrySubmit) {
      <fieldset>
        <legend>input user info.</legend>
         @helper.inputText(userForm("name"))
         @helper.inputText(userForm("email"))
         @helper.inputText(userForm("password"))
    </fieldset>
    <input id="entry" type="submit" value="entry">
  }
}

 最後に、登録結果画面(views/user/entrySubmit.scala.html)を修正します。ここでは、結果として登録したユーザーオブジェクトを受け取り、そのプロパティを表示します。

@(user:User)
@main("entry user submit") {
    <h1>Entry User</h1>
    id:@user.id.get</br>
    name:@user.name</br>
    email:@user.email</br>
    creat date:@user.createDate.get</br>
}

 ここまで記述したら動作確認をしてみましょう。playコンソールからアプリを起動し、/user/entryへアクセスしてみてください。下記のような画面が表示されます。

ユーザー登録画面

 値を入力し、「entry」ボタンをクリックしてみましょう。正しい値であれば、MySQLに入力したデータが登録され、結果画面に表示されます。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。