【问题标题】:Deleting optional fields in DAO models删除 DAO 模型中的可选字段
【发布时间】:2018-01-18 08:05:05
【问题描述】:

我找到了一种从 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 首选方式。

如果有人需要从数据库中删除可选字段,我的问题就开始了。在示例中,它可以是 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)
}

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

【问题讨论】:

  • 您通常会在模型中处理此问题。我不知道您使用的是什么库,但使用anorm,您可以传递Option,如果OptionNone,它将更新为null 列
  • 我明白了,但这种行为违反了“只发送更新的字段”的座右铭。如果一个人仅在 json 有效负载中发送name:"John",则绑定模型将为name=Some("John"), surname=None。在我的情况下,我不想取消姓氏(我不能因为它是必填字段),我只想更新发送的姓名字段。这种行为与我认为有助于前端开发的 react 和 redux 表单库非常相似。
  • 我想我误解了你的问题。不确定是否有首选方法,但我之前遇到过这种方法,并推出了一种新方法来为Some(v) 类型的每个值生成“set x = 'Y'”的List[String]。然后将结果附加到带有.mkString(", ") 的更新查询字符串

标签: scala rest api playframework patch


【解决方案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 一起使用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-03
    • 2013-04-27
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多