0

我正在学习 ReactiveMongo。在我的应用程序中,我想从 MongoDB 检索数据并将其填写到 HTML 表单中。

早些时候我的问题是代码没有编译。我修复了它,但现在我从数据库中得到 None.get 而不是 value。

我在 MongoDB 中的数据将映射到以下案例类

case class User2(
                  name:String,
                  email:String,
                  age:Int,
                  gender:Boolean
                )

以下是 Reactive Mongo 所需的读者。

问题1 - 我从 MongoDB 得到 None.get 而不是 value

object User2{
    implicit object UserReader extends BSONDocumentReader[User2] {
      def read(doc: BSONDocument): User2= {
        val name = doc.getAs[String]("name").get
        val email = doc.getAs[String]("email").get
        val age = doc.getAs[Int]("age").get
        val gender = doc.getAs[Boolean]("gender").get

        User2(name, email, age, gender)
      }
    }
  }

以下是我的控制器代码。忽略不必要的导入

package controllers

import anorm.{NotAssigned, Pk}
import play.api.data.Form
import play.api.data.Form._
import play.api.data.Forms
import play.api.mvc.Controller
import play.api.mvc._
import play.api.data.Forms._
import play.api.data.validation.Constraints._
import play.api.db.DB
import models._
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.util.Try


import reactivemongo.api.MongoDriver
import reactivemongo.bson._
import reactivemongo.api.MongoConnection
import reactivemongo.api.collections.default.BSONCollection



object Application_Test extends Controller {
  val user2Form: Form[User2] = Form(
    mapping(
      "name" -> nonEmptyText,
      "email" -> email,
      "age" -> number,
      "gender" -> boolean
    )(User2.apply)(User2.unapply)
  )

  def index = Action {
    Async {
      val driver = new MongoDriver()
      val connection = driver.connection(List("localhost"))
      val db = connection.db("website-users")
      val collection = db.collection[BSONCollection]("user-table")

      val query = BSONDocument("name" -> "Manu")

      val result = collection.find(query).cursor[User2].collect[List]()
/*    
          result.map { user =>
      //following code doesn't compile. I think result is List[models.User2]. I tried using user and user(0) but none of them compile
            Ok(views.html.HTMLTest(user2Form.fill(user)))
          }
*/

// this version of code compiles

result.map { user => user match {
        case List() => Ok(views.html.HTMLTest(user2Form.fill(User2("a","a@a.com",1,true))))
        case h::v => Ok (views.html.HTMLTest (user2Form.fill (h) ) )
      }
      }
    }
  }
}

以下是 HTML

问题2 - @form("name").value 是从表单中提取值的正确方法吗?

@(form:Form[User2])

<!DOCTYPE html>
<html lang="en" xmlns:font-variant="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-COMPATIBLE" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>HTML Test</title>
    <link rel="stylesheet" type="text/css" href="@routes.Assets.at("stylesheets/bootstrap.min.css")">
    <!--link rel="stylesheet" href="stylesheets/bootstrap-theme.min.css"-->
    <style type="text/css">

        html, body{height:100%; margin:0;padding:0}

.center-form {
  width:100%;
  margin:auto;
  position:relative;
  top:50%;
  transform: translateY(-50%)
}


</style>

</head>
<body>

<div class="container center-form" >

    <!-- for medium and large screens,
    First row of Bootstrap grid contains logo. Total 3 columns (12/4). Logo in middle column-->

    <div class="row" >
        <!--empty column-->
        <div class="col-md-4 col-lg-4" ></div>

        <!--logo column-->
        <div class="col-md-4 col-lg-4" >
            <div>
                <img src="@routes.Assets.at("images/Logo303x64.png")" alt="SalesWorkspace Logo" height="64" width="303">
            </div>
        </div>
        <!--empty column-->
        <div class="col-md-4 col-lg-4"></div>
        </div>

    <!-- for medium and large screens,
    Second row of Bootstrap grid contains the form for username and password. Total 3 columns (12/4). -->
        <div class="row" >
            <!--empty column-->
            <div class="col-md-4 col-lg-4"></div>

            <!--form-->
            <div class="col-md-4 col-lg-4">

            <form>
                    <div class="form-group">
                        <label for="first-name">First Name</label>
                        <input type="text" class="form-control" id="first-name" value="@form("name").value" required>
                    </div>

                    <div class="form-group">
                        <label for="last-name">Last Name</label>
                        <input type="text" class="form-control" id="last-name" value="@form("name").value" required>
                    </div>

                    <div class="form-group">
                        <label for="email">Email</label>
                        <input type="email" class="form-control" id="email" value="@form("email").value" required>
                    </div>
                    <div class="form-group">
                        <label for="password">Password</label>
                        <input type="password" class="form-control" id="password" required>
                    </div>
                    <div class="form-group">
                        <label for="confirm-password">Password</label>
                        <input type="password" class="form-control" id="confirm-password" required>
                    </div>


                    <button type="submit" class="btn btn-primary">Login</button>
                </form>
            </div>
            <!--empty column-->
            <div class="col-md-4 col-lg-4"></div>
        </div>
</div>
<!--script src="@routes.Assets.at("javascripts/jquery-1.9.0.min")"></script-->
<!--script src="@routes.Assets.at("javascripts/bootstrap.min.js")"></script-->
</body>
</html>
4

1 回答 1

0

如 API 文档中所示,BSONDocument.getAs[T]返回一个Option[T]等可用于可选文档字段。

应用.get在这样Option的地方显然是一种代码味道。

如果您想获得一个假定为必需的字段,您最好使用.getAsTry它会在出现错误时提供详细信息(比NoSuchElementExceptionfrom更有帮助None.get)。

def read(doc: BSONDocument): User2= (for {
    name <- doc.getAsTry[String]("name")
    email <- doc.getAsTry[String]("email")
    age <- doc.getAsTry[Int]("age")
    gender <- doc.getAsTry[Boolean]("gender")
  } yield User2(name, email, age, gender)).get
于 2017-02-11T11:59:55.620 回答