문제

I am following play-salat (github.com/leon/play-salat) to create a model for a json input and save to mongodb. How can I create the implicit json read for List collection which might be missing in the input json? The following code gives me the validation error if the 'positions' is missing from input json.

case class LIProfile(
  id: ObjectId = new ObjectId,
  positions: List[Position] = Nil
)

object LIProfile extends LIProfileDAO with LIProfileJson

trait LIProfileDAO extends ModelCompanion[LIProfile, ObjectId] {
  def collection = mongoCollection("liprofiles")
  val dao = new SalatDAO[LIProfile, ObjectId](collection) {}

  // Indexes
  collection.ensureIndex(DBObject("emailAddress" -> 1), "li_profile_email", unique = true)

  // Queries
  def findOneByEmail(email: String): Option[LIProfile] = dao.findOne(MongoDBObject("emailAddress" -> email))
}


trait LIProfileJson {

  implicit val liprofileJsonWrite = new Writes[LIProfile] {
    def writes(p: LIProfile): JsValue = {
      Json.obj(
        "id" -> p.id,
        "positions" -> p.positions
      )
    }
  }
  implicit val liprofileJsonRead = (
    (__ \ 'id).read[ObjectId] ~
    (__ \ 'positions).read (
            (__ \ 'values).read[List[Position]]
            ) 
  )(LIProfile.apply _)
}
도움이 되었습니까?

해결책

Use readNullable in order to retrieve an Option and map that to the contained list or the empty list.

implicit val liprofileJsonRead = (
  (__ \ 'id).read[ObjectId] ~
  (__ \ 'positions).readNullable (
    (__ \ 'values).read[List[Position]]
  ).map {
    case Some(l) => l
    case None => Nil
  }
)(LIProfile)

or even shorter:

implicit val liprofileJsonRead = (
  (__ \ 'id).read[ObjectId] ~
  (__ \ 'positions).readNullable (
    (__ \ 'values).read[List[Position]]
  ).map { l => l.getOrElse(Nil) }
)(LIProfile)

I'm not quite sure what imports you really need here, my code compiles using:

import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top