TypeSafe アクティベーター テンプレートをアプリ (play+reactivemongo+knockoutJS) の基礎として使用しています。
ユーザーを作成しようとしていますが、作成中に、提供された国が既に DB にあることを検証したいと考えています。しかし、プログラムの構造上、その検証を行うのが難しいと感じています。
コード
Object UserContoller extends Controller {
case class UserForm(
firstName: String,
midName: Option[String],
lastName: String,
addr1: String,
addr2: Option[String],
addr3: Option[String],
city: String,
state: Option[String],
zip: String,
country: String,
email: String,
phone: String
) {
def toUser: User = User(
BSONObjectID.generate,
Name(firstName, midName, lastName),
Vector(Email(email)),
Vector(Phone(phone)),
Address(addr1, addr2, addr3, city, state, zip, CountryDao.find(country))
)
}
implicit val userFormFormat = Json.format[UserForm]
def save = Action(parse.json) { req =>
Json.fromJson[UserForm](req.body).fold(
invalid => {
BadRequest("Bad form").flashing(Flash(Map("errors" -> JsError(invalid).toString)))
},
form => Async {
UserDao.save(form.toUser).map(_ => Created.flashing(Flash(Map("result" -> "success"))))
}
)
}
}
私の問題は折りたたむことです:国がDBに存在することを確認する必要があり、ユーザーを作成するために国を取得する必要があります(これは非同期アクションです)。
私の最善のアイデアは、UserForm に「fold」メソッド (Json...fold のように) を提供するものを実装させることです。そのため、国が見つからない場合は無効を返すことができます。存在することがわかっている場合は、MongoDB クエリを作成し、それを待って、Option で .get を実行する方がおそらく簡単です。
私が自分自身を明確にしたことを願っています。
何か案は?
[編集] いくつかの変更を加えて、以下の提案を受け入れました: あなたは私に方向性を与えましたが、私はそれを少し修正しました: [文字列] 国名の代わりに国をパラメータとして取るように UserForm クラスを変更しました。リストをレンダリングするテンプレートにリストを渡すと、選択した国が JSON 化され、そのままアップロードされると考えました (国には json.format があります)。
私は CountryDao に exists(c: Country) メソッドを作成しました。これは、DB を検索して結果を返すだけです。
次に、saveUserを次のように変更しました:
...
form => Async {
CountryDao.exists(form.country) match {
case c if c==true => {
UserDao.save(form.toUser map {_ =>
Created.flashing(Flash(Map("result" -> "success")))
}
}
case c if c==false => {
Future(BadRequest("Invalid Country").flashing(
Flash(Map("errors" -> "Invalid Country"))))
}
}
}
そしてコンパイルします。それも機能するかどうか見てみましょう:)
とにかく、今のところ解決したと思います。ありがとうございます