玩anorm,从json创建一个模型而不在json中传递anorm PK值

object Users  {

  implicit object UserReads extends Reads[User] {
    def reads(json: JsValue) = JsSuccess(User(
      Id((json \ "id").as[String].toLong),
      (json \ "name").as[String],
      (json \ "email").as[String]
  }
  implicit object UserWrites extends Writes[User] {
    def writes(user: User) = JsObject(Seq(
      "id" -> JsNumber(user.id.get),
      "name" -> JsString(user.name),
      "email" -> Json.toJson(user.email)
  }

  def view(id: Long) = Action { implicit request =>
    Ok(Json.toJson(User.find(id)))
  }

  def all() = Action { implicit request =>
    Ok(Json.toJson(User.findAll()))
  }

  def save = Action(parse.json) { request =>
    val userJson = request.body
    val user = userJson.as[User]
    try {
      User.create(user)
      Ok("Saved")
    } catch {
      case e: IllegalArgumentException => BadRequest("Error")
    }
  }
}


case class User(
  id: Pk[Long] = NotAssigned,
  name: String = "",
  email: String = "")

以上两个是我的控制器&模型,当我使用angular JS将用户数据[id,name,email]发送为json时,它会在数据库中创建User对象.但是当我只输入[name,email]或[name]时它应该可以创建,因为电子邮件可能为null.如果我没有错,我应该在User的读写方法中调整这些,是吗?

此外,我们可以为不同的目标进行两次读/写操作,如果是这样,如何实现 – 抛出一些光.谢谢.

一个问题修复如下:

case class User(
  id: Pk[Long] = NotAssigned,
  name: String = "",
  email: Option[String])

implicit object UserReads extends Reads[User] {
    def reads(json: JsValue) = JsSuccess(User(
      Id((json \ "id").as[String].toLong),
      (json \ "name").as[String],
      (json \ "email").asOpt[String])
  }
  implicit object UserWrites extends Writes[User] {
    def writes(user: User) = JsObject(Seq(
      "id" -> JsNumber(user.id.get),
      "name" -> JsString(user.name),
      "email" -> Json.toJson(user.email))
  }

现在电子邮件可以为null,但是如何id – PK [Long]

最佳答案 我没有编译它,但它应该工作:

case class User(
  id: Pk[Long] = NotAssigned,
  name: String = "",
  email: Option[String])

implicit object UserReads extends Reads[User] {
    def reads(json: JsValue) = JsSuccess(User(
      (json \ "id").asOpt[Long].map(id => Id[Long](id)).getOrElse(NotAssigned)
      (json \ "name").as[String],
      (json \ "email").asOpt[String])
  }
  implicit object UserWrites extends Writes[User] {
    def writes(user: User) = JsObject(Seq(
      "id" -> JsNumber(user.id.get),
      "name" -> JsString(user.name),
      "email" -> Json.toJson(user.email))
  }

基本上你把id作为Option [Long]就像你用电子邮件一样.然后检查它是否已设置,如果是,则使用Id [Long](id)创建Pk实例,如果不是,则提供NotAssigned Pk单例实例.

附加提示

或者你可以尝试使用

implicit val jsonFormatter = Json.format[User]

它将在编译时直接为您创建Reads和Writes.
如果您直接使用anorm对象,则有两个问题:

首先你需要一个Pk格式[长]

implicit object PkLongFormat extends Format[Pk[Long]] {
  def reads(json: JsValue): JsResult[Pk[Long]] = {
    json.asOpt[Long].map {
      id => JsSuccess(Id[Long](id))
    }.getOrElse(JsSuccess(NotAssigned))
  }
  def writes(id: Pk[Long]): JsNumber = JsNumber(id.get)
}

第二,它不起作用,如果你根本不发送id,甚至没有值null,所以你的客户端需要发送{“id”:null,“name”:“Tim”}因为它甚至没有尝试调用可以处理JsUndefined的PkFormatter,但只是给你一个“validate.error.missing-path”错误

如果您不想发送空ID,则无法使用宏Json.format [User]

点赞