Playのグローバルな設定&spec2でBDDなテスト:Scala+Play 2.0でWebアプリ開発入門(8)(2/4 ページ)
2.0からScalaに対応したWebアプリ開発の人気軽量フレームワーク「Play」について解説し、Webアプリの作り方を紹介する入門連載。今回は、アプリ起動/停止前後やエラー発生時などで使えるGlobalオブジェクトや、さまざまなテストについて解説。Selenium WebDriverを使ったブラウザテストも。
ユーザー登録アプリの修正
テストを作成する前に、ユーザー登録機能を修正します。モデル・コントローラ・テンプレートを修正し、サービスクラスを新たに追加します。
モデル修正
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.