Я пытался преобразовать результаты из формы scala (сопоставленной с моделью класса) в json object
, чтобы вставить эти данные в коллекцию (база данных Mongo). Я использую Play Framework с ReactiveMongo Plugin (с поддержкой JSON, а не BSON). Модели и форма выглядят так:
case class LastVisit(selection: String = "", date: Option[Date] = None) extends ReadAndWriteTrait
case class AdminM(_id: Option[BSONObjectID], adminCreatedId: Option[Int], dateCreated: Option[Date], adminModifiedId: Option[Int], lastModified: Option[Date]) extends ReadAndWriteTrait
case class MyClass(usrId: Option[BSONObjectID] = None, numOfVisits: Option[Int] = None, lastVisit_e: Option[LastVisit] = None, admin_e: Option[AdminM]) extends SuperVarT with ReadAndWriteTrait
object MyClass extends SuperFormT with ReadAndWriteTrait {
implicit val lastVisitFormat: OFormat[LastVisit] = Json.format[LastVisit]
implicit val adminMFormat: OFormat[AdminM] = Json.format[AdminM]
implicit val myClassFormat: OFormat[MyClass] = Json.format[MyClass]
val form = Form(
mapping(
"usrId" -> optional(
text.transform(str2bson, bson2str)
),
"numOfVisits" -> optional(number),
"lastVisit_e" -> optional(mapping(
"selection" -> nonEmptyText,
"date" -> optional(date)
)(LastVisit.apply)(LastVisit.unapply)),
"admin_e" -> optional(mapping(
"_id" -> ignored(Option.empty[BSONObjectID]),
"adminCreatedId" -> optional(number),
"dateCreated" -> optional(date),
"adminModifiedId" -> optional(number),
"lastModified" -> optional(date).transform(date2Date, date2NowDate)
)(AdminM.apply)(AdminM.unapply))
)(MyClass.apply)(MyClass.unapply)
)
trait ReadAndWriteTrait {
implicit val dateRead: Reads[Date] = (__ \ "$date").read[Long].map {
date => new Date(date)
}
implicit val dateWrite: Writes[Date] = new Writes[Date] {
def writes(date: Date): JsValue = Json.obj(
"$date" -> date.getTime
)
}
}
К сожалению, поле lastVisit_e.date
вставляется в базу данных как номер типа Long
вместо ISODate("date here")
, что в Json сделано с Json.obj(s"$$date" -> JsNumber(dateLong here))
, как указано в документации . Вот функция Action
, к которой я направляюсь, которая будет использоваться для обновления данных из формы в коллекцию Mongo . Я только что настроил его, чтобы дать мне вывод, чтобы я мог видеть, что дата не форматируется правильно:
def updateFromForm(collName: String, oId: Option[BSONObjectID], activeTabIdx: Int = 0) = Action.async { implicit request: Request[AnyContent] =>
MyClass.form.bindFromRequest.fold(
errorForm => Future.successful(Ok("TODO")),
data => {
/*
// todo - uncomment when formatting is correct
val doc = apiC.prepareData(data) // function used to transform/prepare data
update(collName, oId, doc, activeTabIdx)(request) // function to be called to update db collection
*/
val doc = Json.toJson(doc) // for test purposes
Future(Ok(doc.toString())) // for test purposes
}
)
}
Это типичный ответ, который я получаю:
{
"usrId":{
"$oid":"5a28258d9830b7614f566cc7"
},
"numOfVisits":5,
"lastVisit_e":{
"selection":"departure date",
"date":1496271600000
}
}
usrId
выводится правильно (как $oid: "5a28258d9830b7614f566cc7"
), но lastVisit_e.date
отображается как Long
число. Как я могу получить это правильно? Если есть какие-либо разъяснения, пожалуйста, дайте мне знать. Большое спасибо.