删除DAO模型中的可选字段

时间:2018-01-18 08:05:05

标签: scala rest api playframework patch

我找到了一种从http请求更新数据库模型的方法,如下所示;

case class DatabasePerson(
  id: Int,
  name: Option[String],
  surname: String
)

case class PersonUpdateRequest(
 name: Option[String],
 surname: Option[String]
) {
  def update(databasePerson: DatabasePerson) = databasePerson.copy(
    name = name.orElse(databasePerson.name),
    surname = surname.getOrElse(databasePerson.surname)
  )
}

通过这种方式,我可以更新客户端中唯一发送的字段。我认为只有更新(或触及)字段才能在诸如react等技术中以api首选方式发送。

如果某人需要从db中删除可选字段,我的问题就会开始。在示例中,它可以是name

我想到的唯一方法是期望无效值,例如""。因此,调整此类协议的更新模型将如下所示;

case class PersonUpdateRequest(
  name: Option[String],
  surname: Option[String]
) {
  def update(databasePerson: DatabasePerson) = databasePerson.copy(
    name = if (name.exists(_.isEmpty)) None else name.orElse(databasePerson.name),
    surname = surname.getOrElse(databasePerson.surname)
  )
}

这仅适用于字符串,但我也有日期,数字或复杂模型。正如你所看到的,为所有领域写作都有点乏味。

我正在使用play框架进行验证,因此对于更新请求有一个这样的映射器;

object PersonUpdateRequest {
  lazy val map = mapping(
    "name" -> optional(text),
    "surname" -> optional(text)
  )(apply)(unapply)
}

删除更新方法上的可选字段的首选方法是什么。 感谢。

1 个答案:

答案 0 :(得分:1)

您可以采用适合您的数据模型的一种方法是在您的选项上添加其他级别的Option

case class PersonUpdateRequest(
 name: Option[String],
 surname: Option[Option[String]]
)

所以你可以拥有这些案件:

surname == Some(Some("foo")) // set surname to "foo"
surname == Some(None) // set surname to None == delete the value in the db
surname == None // do not update

这意味着要使用自定义映射器。这可能适用于自定义json阅读器Reads[Option[Option[T]]。类似的东西:

JsUndefined => None
JsNull => Some(None)
JsString(value) => Some(Some(value)

但我不确定如何将其与Form

一起使用